/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef jit_shared_BaselineCompiler_shared_h #define jit_shared_BaselineCompiler_shared_h #include "jit/BaselineFrameInfo.h" #include "jit/BaselineIC.h" #include "jit/BytecodeAnalysis.h" #include "jit/MacroAssembler.h" namespace js { namespace jit { class BaselineCompilerShared { protected: JSContext* cx; JSScript* script; jsbytecode* pc; MacroAssembler masm; bool ionCompileable_; bool ionOSRCompileable_; bool compileDebugInstrumentation_; TempAllocator& alloc_; BytecodeAnalysis analysis_; FrameInfo frame; FallbackICStubSpace stubSpace_; js::Vector icEntries_; // Stores the native code offset for a bytecode pc. struct PCMappingEntry { uint32_t pcOffset; uint32_t nativeOffset; PCMappingSlotInfo slotInfo; // If set, insert a PCMappingIndexEntry before encoding the // current entry. bool addIndexEntry; }; js::Vector pcMappingEntries_; // Labels for the 'movWithPatch' for loading IC entry pointers in // the generated IC-calling code in the main jitcode. These need // to be patched with the actual icEntry offsets after the BaselineScript // has been allocated. struct ICLoadLabel { size_t icEntry; CodeOffset label; }; js::Vector icLoadLabels_; uint32_t pushedBeforeCall_; #ifdef DEBUG bool inCall_; #endif CodeOffset spsPushToggleOffset_; CodeOffset profilerEnterFrameToggleOffset_; CodeOffset profilerExitFrameToggleOffset_; Vector traceLoggerToggleOffsets_; CodeOffset traceLoggerScriptTextIdOffset_; BaselineCompilerShared(JSContext* cx, TempAllocator& alloc, JSScript* script); BaselineICEntry* allocateICEntry(ICStub* stub, ICEntry::Kind kind) { if (!stub) return nullptr; // Create the entry and add it to the vector. if (!icEntries_.append(BaselineICEntry(script->pcToOffset(pc), kind))) { ReportOutOfMemory(cx); return nullptr; } BaselineICEntry& vecEntry = icEntries_.back(); // Set the first stub for the IC entry to the fallback stub vecEntry.setFirstStub(stub); // Return pointer to the IC entry return &vecEntry; } // Append an ICEntry without a stub. bool appendICEntry(ICEntry::Kind kind, uint32_t returnOffset) { BaselineICEntry entry(script->pcToOffset(pc), kind); entry.setReturnOffset(CodeOffset(returnOffset)); if (!icEntries_.append(entry)) { ReportOutOfMemory(cx); return false; } return true; } bool addICLoadLabel(CodeOffset label) { MOZ_ASSERT(!icEntries_.empty()); ICLoadLabel loadLabel; loadLabel.label = label; loadLabel.icEntry = icEntries_.length() - 1; if (!icLoadLabels_.append(loadLabel)) { ReportOutOfMemory(cx); return false; } return true; } JSFunction* function() const { // Not delazifying here is ok as the function is guaranteed to have // been delazified before compilation started. return script->functionNonDelazifying(); } ModuleObject* module() const { return script->module(); } PCMappingSlotInfo getStackTopSlotInfo() { MOZ_ASSERT(frame.numUnsyncedSlots() <= 2); switch (frame.numUnsyncedSlots()) { case 0: return PCMappingSlotInfo::MakeSlotInfo(); case 1: return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1))); case 2: default: return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1)), PCMappingSlotInfo::ToSlotLocation(frame.peek(-2))); } } template void pushArg(const T& t) { masm.Push(t); } void prepareVMCall(); enum CallVMPhase { POST_INITIALIZE, PRE_INITIALIZE, CHECK_OVER_RECURSED }; bool callVM(const VMFunction& fun, CallVMPhase phase=POST_INITIALIZE); bool callVMNonOp(const VMFunction& fun, CallVMPhase phase=POST_INITIALIZE) { if (!callVM(fun, phase)) return false; icEntries_.back().setFakeKind(ICEntry::Kind_NonOpCallVM); return true; } public: BytecodeAnalysis& analysis() { return analysis_; } void setCompileDebugInstrumentation() { compileDebugInstrumentation_ = true; } }; } // namespace jit } // namespace js #endif /* jit_shared_BaselineCompiler_shared_h */