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 "jscntxt.h" 8 #include "jscompartment.h" 9 10 #include "jit/Bailouts.h" 11 #include "jit/JitCompartment.h" 12 13 using namespace js; 14 using namespace js::jit; 15 16 #if defined(_WIN32) 17 # pragma pack(push, 1) 18 #endif 19 20 namespace js { 21 namespace jit { 22 23 class BailoutStack 24 { 25 uintptr_t frameClassId_; 26 RegisterDump::FPUArray fpregs_; 27 RegisterDump::GPRArray regs_; 28 union { 29 uintptr_t frameSize_; 30 uintptr_t tableOffset_; 31 }; 32 uintptr_t snapshotOffset_; 33 34 public: frameClass() const35 FrameSizeClass frameClass() const { 36 return FrameSizeClass::FromClass(frameClassId_); 37 } tableOffset() const38 uintptr_t tableOffset() const { 39 MOZ_ASSERT(frameClass() != FrameSizeClass::None()); 40 return tableOffset_; 41 } frameSize() const42 uint32_t frameSize() const { 43 if (frameClass() == FrameSizeClass::None()) 44 return frameSize_; 45 return frameClass().frameSize(); 46 } machine()47 MachineState machine() { 48 return MachineState::FromBailout(regs_, fpregs_); 49 } snapshotOffset() const50 SnapshotOffset snapshotOffset() const { 51 MOZ_ASSERT(frameClass() == FrameSizeClass::None()); 52 return snapshotOffset_; 53 } parentStackPointer() const54 uint8_t* parentStackPointer() const { 55 if (frameClass() == FrameSizeClass::None()) 56 return (uint8_t*)this + sizeof(BailoutStack); 57 return (uint8_t*)this + offsetof(BailoutStack, snapshotOffset_); 58 } 59 }; 60 61 } // namespace jit 62 } // namespace js 63 64 #if defined(_WIN32) 65 # pragma pack(pop) 66 #endif 67 BailoutFrameInfo(const JitActivationIterator & activations,BailoutStack * bailout)68BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& activations, 69 BailoutStack* bailout) 70 : machine_(bailout->machine()) 71 { 72 uint8_t* sp = bailout->parentStackPointer(); 73 framePointer_ = sp + bailout->frameSize(); 74 topFrameSize_ = framePointer_ - sp; 75 76 JSScript* script = ScriptFromCalleeToken(((JitFrameLayout*) framePointer_)->calleeToken()); 77 JitActivation* activation = activations.activation()->asJit(); 78 topIonScript_ = script->ionScript(); 79 80 attachOnJitActivation(activations); 81 82 if (bailout->frameClass() == FrameSizeClass::None()) { 83 snapshotOffset_ = bailout->snapshotOffset(); 84 return; 85 } 86 87 // Compute the snapshot offset from the bailout ID. 88 JSRuntime* rt = activation->compartment()->runtimeFromMainThread(); 89 JitCode* code = rt->jitRuntime()->getBailoutTable(bailout->frameClass()); 90 uintptr_t tableOffset = bailout->tableOffset(); 91 uintptr_t tableStart = reinterpret_cast<uintptr_t>(code->raw()); 92 93 MOZ_ASSERT(tableOffset >= tableStart && 94 tableOffset < tableStart + code->instructionsSize()); 95 MOZ_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0); 96 97 uint32_t bailoutId = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1; 98 MOZ_ASSERT(bailoutId < BAILOUT_TABLE_SIZE); 99 100 snapshotOffset_ = topIonScript_->bailoutToSnapshot(bailoutId); 101 } 102 BailoutFrameInfo(const JitActivationIterator & activations,InvalidationBailoutStack * bailout)103BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& activations, 104 InvalidationBailoutStack* bailout) 105 : machine_(bailout->machine()) 106 { 107 framePointer_ = (uint8_t*) bailout->fp(); 108 topFrameSize_ = framePointer_ - bailout->sp(); 109 topIonScript_ = bailout->ionScript(); 110 attachOnJitActivation(activations); 111 112 uint8_t* returnAddressToFp_ = bailout->osiPointReturnAddress(); 113 const OsiIndex* osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_); 114 snapshotOffset_ = osiIndex->snapshotOffset(); 115 } 116