| Index: src/safepoint-table.h
|
| diff --git a/src/safepoint-table.h b/src/safepoint-table.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..010ac5759bee7413ad27929783516209625aeafc
|
| --- /dev/null
|
| +++ b/src/safepoint-table.h
|
| @@ -0,0 +1,189 @@
|
| +// Copyright 2010 the V8 project authors. All rights reserved.
|
| +// Redistribution and use in source and binary forms, with or without
|
| +// modification, are permitted provided that the following conditions are
|
| +// met:
|
| +//
|
| +// * Redistributions of source code must retain the above copyright
|
| +// notice, this list of conditions and the following disclaimer.
|
| +// * Redistributions in binary form must reproduce the above
|
| +// copyright notice, this list of conditions and the following
|
| +// disclaimer in the documentation and/or other materials provided
|
| +// with the distribution.
|
| +// * Neither the name of Google Inc. nor the names of its
|
| +// contributors may be used to endorse or promote products derived
|
| +// from this software without specific prior written permission.
|
| +//
|
| +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| +
|
| +#ifndef V8_SAFEPOINT_TABLE_H_
|
| +#define V8_SAFEPOINT_TABLE_H_
|
| +
|
| +#include "v8.h"
|
| +
|
| +#include "macro-assembler.h"
|
| +#include "zone.h"
|
| +#include "zone-inl.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +
|
| +class SafepointTable BASE_EMBEDDED {
|
| + public:
|
| + explicit SafepointTable(Code* code);
|
| +
|
| + int size() const {
|
| + return kHeaderSize +
|
| + (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); }
|
| + unsigned length() const { return length_; }
|
| + unsigned entry_size() const { return entry_size_; }
|
| +
|
| + unsigned GetPcOffset(unsigned index) const {
|
| + ASSERT(index < length_);
|
| + return Memory::uint32_at(GetPcOffsetLocation(index));
|
| + }
|
| +
|
| + int GetDeoptimizationIndex(unsigned index) const {
|
| + ASSERT(index < length_);
|
| + unsigned value = Memory::uint32_at(GetDeoptimizationLocation(index));
|
| + return DeoptimizationIndexField::decode(value);
|
| + }
|
| +
|
| + unsigned GetGapCodeSize(unsigned index) const {
|
| + ASSERT(index < length_);
|
| + unsigned value = Memory::uint32_at(GetDeoptimizationLocation(index));
|
| + return GapCodeSizeField::decode(value);
|
| + }
|
| +
|
| + uint8_t* GetEntry(unsigned index) const {
|
| + ASSERT(index < length_);
|
| + return &Memory::uint8_at(entries_ + (index * entry_size_));
|
| + }
|
| +
|
| + class GapCodeSizeField: public BitField<unsigned, 0, 8> {};
|
| + class DeoptimizationIndexField: public BitField<int, 8, 24> {};
|
| +
|
| + static bool HasRegisters(uint8_t* entry);
|
| + static bool HasRegisterAt(uint8_t* entry, int reg_index);
|
| +
|
| + void PrintEntry(unsigned index) const;
|
| +
|
| + private:
|
| + static const uint8_t kNoRegisters = 0xFF;
|
| +
|
| + static const int kLengthOffset = 0;
|
| + static const int kEntrySizeOffset = kLengthOffset + kIntSize;
|
| + static const int kHeaderSize = kEntrySizeOffset + kIntSize;
|
| +
|
| + static const int kPcSize = kIntSize;
|
| + static const int kDeoptimizationIndexSize = kIntSize;
|
| + static const int kPcAndDeoptimizationIndexSize =
|
| + kPcSize + kDeoptimizationIndexSize;
|
| +
|
| + Address GetPcOffsetLocation(unsigned index) const {
|
| + return pc_and_deoptimization_indexes_ +
|
| + (index * kPcAndDeoptimizationIndexSize);
|
| + }
|
| +
|
| + Address GetDeoptimizationLocation(unsigned index) const {
|
| + return GetPcOffsetLocation(index) + kPcSize;
|
| + }
|
| +
|
| + static void PrintBits(uint8_t byte, int digits);
|
| +
|
| + AssertNoAllocation no_allocation_;
|
| + Code* code_;
|
| + unsigned length_;
|
| + unsigned entry_size_;
|
| +
|
| + Address pc_and_deoptimization_indexes_;
|
| + Address entries_;
|
| +
|
| + friend class SafepointTableBuilder;
|
| +};
|
| +
|
| +
|
| +class Safepoint BASE_EMBEDDED {
|
| + public:
|
| + static const int kNoDeoptimizationIndex = 0x00ffffff;
|
| +
|
| + void DefinePointerSlot(int index) { indexes_->Add(index); }
|
| + void DefinePointerRegister(Register reg) { registers_->Add(reg.code()); }
|
| +
|
| + private:
|
| + Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers) :
|
| + indexes_(indexes), registers_(registers) { }
|
| + ZoneList<int>* indexes_;
|
| + ZoneList<int>* registers_;
|
| +
|
| + friend class SafepointTableBuilder;
|
| +};
|
| +
|
| +
|
| +class SafepointTableBuilder BASE_EMBEDDED {
|
| + public:
|
| + SafepointTableBuilder()
|
| + : deoptimization_info_(32),
|
| + indexes_(32),
|
| + registers_(32),
|
| + emitted_(false) { }
|
| +
|
| + // Get the offset of the emitted safepoint table in the code.
|
| + unsigned GetCodeOffset() const;
|
| +
|
| + // Define a new safepoint for the current position in the body.
|
| + Safepoint DefineSafepoint(
|
| + Assembler* assembler,
|
| + int deoptimization_index = Safepoint::kNoDeoptimizationIndex);
|
| +
|
| + // Define a new safepoint with registers on the stack for the
|
| + // current position in the body and take the number of arguments on
|
| + // top of the registers into account.
|
| + Safepoint DefineSafepointWithRegisters(
|
| + Assembler* assembler,
|
| + int arguments,
|
| + int deoptimization_index = Safepoint::kNoDeoptimizationIndex);
|
| +
|
| + // Update the last safepoint with the size of the code generated for the gap
|
| + // following it.
|
| + void SetPcAfterGap(int pc) {
|
| + ASSERT(!deoptimization_info_.is_empty());
|
| + int index = deoptimization_info_.length() - 1;
|
| + deoptimization_info_[index].pc_after_gap = pc;
|
| + }
|
| +
|
| + // Emit the safepoint table after the body. The number of bits per
|
| + // entry must be enough to hold all the pointer indexes.
|
| + void Emit(Assembler* assembler, int bits_per_entry);
|
| +
|
| + private:
|
| + struct DeoptimizationInfo {
|
| + unsigned pc;
|
| + unsigned deoptimization_index;
|
| + unsigned pc_after_gap;
|
| + };
|
| +
|
| + uint32_t EncodeDeoptimizationIndexAndGap(DeoptimizationInfo info);
|
| +
|
| + ZoneList<DeoptimizationInfo> deoptimization_info_;
|
| + ZoneList<ZoneList<int>*> indexes_;
|
| + ZoneList<ZoneList<int>*> registers_;
|
| +
|
| + bool emitted_;
|
| + unsigned offset_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder);
|
| +};
|
| +
|
| +} } // namespace v8::internal
|
| +
|
| +#endif // V8_SAFEPOINT_TABLE_H_
|
|
|