diff -r 000000000000 -r 6474c204b198 js/src/jit/x86/Bailouts-x86.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/js/src/jit/x86/Bailouts-x86.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,116 @@ +/* -*- 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/. */ + +#include "jscntxt.h" +#include "jscompartment.h" + +#include "jit/Bailouts.h" +#include "jit/JitCompartment.h" + +using namespace js; +using namespace js::jit; + +#if defined(_WIN32) +# pragma pack(push, 1) +#endif + +namespace js { +namespace jit { + +class BailoutStack +{ + uintptr_t frameClassId_; + mozilla::Array fpregs_; + mozilla::Array regs_; + union { + uintptr_t frameSize_; + uintptr_t tableOffset_; + }; + uintptr_t snapshotOffset_; + + public: + FrameSizeClass frameClass() const { + return FrameSizeClass::FromClass(frameClassId_); + } + uintptr_t tableOffset() const { + JS_ASSERT(frameClass() != FrameSizeClass::None()); + return tableOffset_; + } + uint32_t frameSize() const { + if (frameClass() == FrameSizeClass::None()) + return frameSize_; + return frameClass().frameSize(); + } + MachineState machine() { + return MachineState::FromBailout(regs_, fpregs_); + } + SnapshotOffset snapshotOffset() const { + JS_ASSERT(frameClass() == FrameSizeClass::None()); + return snapshotOffset_; + } + uint8_t *parentStackPointer() const { + if (frameClass() == FrameSizeClass::None()) + return (uint8_t *)this + sizeof(BailoutStack); + return (uint8_t *)this + offsetof(BailoutStack, snapshotOffset_); + } +}; + +} // namespace jit +} // namespace js + +#if defined(_WIN32) +# pragma pack(pop) +#endif + +IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations, + BailoutStack *bailout) + : JitFrameIterator(activations), + machine_(bailout->machine()) +{ + uint8_t *sp = bailout->parentStackPointer(); + uint8_t *fp = sp + bailout->frameSize(); + + current_ = fp; + type_ = JitFrame_IonJS; + topFrameSize_ = current_ - sp; + topIonScript_ = script()->ionScript(); + + if (bailout->frameClass() == FrameSizeClass::None()) { + snapshotOffset_ = bailout->snapshotOffset(); + return; + } + + // Compute the snapshot offset from the bailout ID. + JitActivation *activation = activations.activation()->asJit(); + JSRuntime *rt = activation->compartment()->runtimeFromMainThread(); + JitCode *code = rt->jitRuntime()->getBailoutTable(bailout->frameClass()); + uintptr_t tableOffset = bailout->tableOffset(); + uintptr_t tableStart = reinterpret_cast(code->raw()); + + JS_ASSERT(tableOffset >= tableStart && + tableOffset < tableStart + code->instructionsSize()); + JS_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0); + + uint32_t bailoutId = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1; + JS_ASSERT(bailoutId < BAILOUT_TABLE_SIZE); + + snapshotOffset_ = topIonScript_->bailoutToSnapshot(bailoutId); +} + +IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations, + InvalidationBailoutStack *bailout) + : JitFrameIterator(activations), + machine_(bailout->machine()) +{ + returnAddressToFp_ = bailout->osiPointReturnAddress(); + topIonScript_ = bailout->ionScript(); + const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_); + + current_ = (uint8_t*) bailout->fp(); + type_ = JitFrame_IonJS; + topFrameSize_ = current_ - bailout->sp(); + snapshotOffset_ = osiIndex->snapshotOffset(); +}