LCOV - code coverage report
Current view: top level - js/src/jit/shared - BaselineCompiler-shared.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 44 65 67.7 %
Date: 2017-07-14 16:53:18 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "jit/shared/BaselineCompiler-shared.h"
       8             : 
       9             : #include "jit/BaselineIC.h"
      10             : #include "jit/VMFunctions.h"
      11             : 
      12             : #include "jsscriptinlines.h"
      13             : #include "jit/MacroAssembler-inl.h"
      14             : 
      15             : using namespace js;
      16             : using namespace js::jit;
      17             : 
      18         628 : BaselineCompilerShared::BaselineCompilerShared(JSContext* cx, TempAllocator& alloc, JSScript* script)
      19             :   : cx(cx),
      20             :     script(script),
      21         628 :     pc(script->code()),
      22         628 :     ionCompileable_(jit::IsIonEnabled(cx) && CanIonCompileScript(cx, script, false)),
      23         628 :     ionOSRCompileable_(jit::IsIonEnabled(cx) && CanIonCompileScript(cx, script, true)),
      24         628 :     compileDebugInstrumentation_(script->isDebuggee()),
      25             :     alloc_(alloc),
      26             :     analysis_(alloc, script),
      27             :     frame(script, masm),
      28             :     stubSpace_(),
      29             :     icEntries_(),
      30             :     pcMappingEntries_(),
      31             :     icLoadLabels_(),
      32             :     pushedBeforeCall_(0),
      33             : #ifdef DEBUG
      34             :     inCall_(false),
      35             : #endif
      36             :     profilerPushToggleOffset_(),
      37             :     profilerEnterFrameToggleOffset_(),
      38             :     profilerExitFrameToggleOffset_(),
      39             :     traceLoggerToggleOffsets_(cx),
      40        3140 :     traceLoggerScriptTextIdOffset_()
      41         628 : { }
      42             : 
      43             : void
      44        3436 : BaselineCompilerShared::prepareVMCall()
      45             : {
      46        3436 :     pushedBeforeCall_ = masm.framePushed();
      47             : #ifdef DEBUG
      48        3436 :     inCall_ = true;
      49             : #endif
      50             : 
      51             :     // Ensure everything is synced.
      52        3436 :     frame.syncStack(0);
      53             : 
      54             :     // Save the frame pointer.
      55        3436 :     masm.Push(BaselineFrameReg);
      56        3436 : }
      57             : 
      58             : bool
      59        3436 : BaselineCompilerShared::callVM(const VMFunction& fun, CallVMPhase phase)
      60             : {
      61        3436 :     JitCode* code = cx->runtime()->jitRuntime()->getVMWrapper(fun);
      62        3436 :     if (!code)
      63           0 :         return false;
      64             : 
      65             : #ifdef DEBUG
      66             :     // Assert prepareVMCall() has been called.
      67        3436 :     MOZ_ASSERT(inCall_);
      68        3436 :     inCall_ = false;
      69             : 
      70             :     // Assert the frame does not have an override pc when we're executing JIT code.
      71             :     {
      72        6872 :         Label ok;
      73        6872 :         masm.branchTest32(Assembler::Zero, frame.addressOfFlags(),
      74        3436 :                           Imm32(BaselineFrame::HAS_OVERRIDE_PC), &ok);
      75        3436 :         masm.assumeUnreachable("BaselineFrame shouldn't override pc when executing JIT code");
      76        3436 :         masm.bind(&ok);
      77             :     }
      78             : #endif
      79             : 
      80             :     // Compute argument size. Note that this include the size of the frame pointer
      81             :     // pushed by prepareVMCall.
      82        3436 :     uint32_t argSize = fun.explicitStackSlots() * sizeof(void*) + sizeof(void*);
      83             : 
      84             :     // Assert all arguments were pushed.
      85        3436 :     MOZ_ASSERT(masm.framePushed() - pushedBeforeCall_ == argSize);
      86             : 
      87        3436 :     Address frameSizeAddress(BaselineFrameReg, BaselineFrame::reverseOffsetOfFrameSize());
      88        3436 :     uint32_t frameVals = frame.nlocals() + frame.stackDepth();
      89        3436 :     uint32_t frameBaseSize = BaselineFrame::FramePointerOffset + BaselineFrame::Size();
      90        3436 :     uint32_t frameFullSize = frameBaseSize + (frameVals * sizeof(Value));
      91        3436 :     if (phase == POST_INITIALIZE) {
      92        3436 :         masm.store32(Imm32(frameFullSize), frameSizeAddress);
      93        3436 :         uint32_t descriptor = MakeFrameDescriptor(frameFullSize + argSize, JitFrame_BaselineJS,
      94        6872 :                                                   ExitFrameLayout::Size());
      95        3436 :         masm.push(Imm32(descriptor));
      96             : 
      97           0 :     } else if (phase == PRE_INITIALIZE) {
      98           0 :         masm.store32(Imm32(frameBaseSize), frameSizeAddress);
      99           0 :         uint32_t descriptor = MakeFrameDescriptor(frameBaseSize + argSize, JitFrame_BaselineJS,
     100           0 :                                                   ExitFrameLayout::Size());
     101           0 :         masm.push(Imm32(descriptor));
     102             : 
     103             :     } else {
     104           0 :         MOZ_ASSERT(phase == CHECK_OVER_RECURSED);
     105           0 :         Label afterWrite;
     106           0 :         Label writePostInitialize;
     107             : 
     108             :         // If OVER_RECURSED is set, then frame locals haven't been pushed yet.
     109           0 :         masm.branchTest32(Assembler::Zero,
     110           0 :                           frame.addressOfFlags(),
     111             :                           Imm32(BaselineFrame::OVER_RECURSED),
     112           0 :                           &writePostInitialize);
     113             : 
     114           0 :         masm.move32(Imm32(frameBaseSize), ICTailCallReg);
     115           0 :         masm.jump(&afterWrite);
     116             : 
     117           0 :         masm.bind(&writePostInitialize);
     118           0 :         masm.move32(Imm32(frameFullSize), ICTailCallReg);
     119             : 
     120           0 :         masm.bind(&afterWrite);
     121           0 :         masm.store32(ICTailCallReg, frameSizeAddress);
     122           0 :         masm.add32(Imm32(argSize), ICTailCallReg);
     123           0 :         masm.makeFrameDescriptor(ICTailCallReg, JitFrame_BaselineJS, ExitFrameLayout::Size());
     124           0 :         masm.push(ICTailCallReg);
     125             :     }
     126        3436 :     MOZ_ASSERT(fun.expectTailCall == NonTailCall);
     127             :     // Perform the call.
     128        3436 :     masm.call(code);
     129        3436 :     uint32_t callOffset = masm.currentOffset();
     130        3436 :     masm.pop(BaselineFrameReg);
     131             : 
     132             : #ifdef DEBUG
     133             :     // Assert the frame does not have an override pc when we're executing JIT code.
     134             :     {
     135        6872 :         Label ok;
     136        6872 :         masm.branchTest32(Assembler::Zero, frame.addressOfFlags(),
     137        3436 :                           Imm32(BaselineFrame::HAS_OVERRIDE_PC), &ok);
     138        3436 :         masm.assumeUnreachable("BaselineFrame shouldn't override pc after VM call");
     139        3436 :         masm.bind(&ok);
     140             :     }
     141             : #endif
     142             : 
     143             :     // Add a fake ICEntry (without stubs), so that the return offset to
     144             :     // pc mapping works.
     145        3436 :     return appendICEntry(ICEntry::Kind_CallVM, callOffset);
     146             : }

Generated by: LCOV version 1.13