diff options
Diffstat (limited to 'deps/v8/src/interpreter/constant-array-builder.cc')
-rw-r--r-- | deps/v8/src/interpreter/constant-array-builder.cc | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/deps/v8/src/interpreter/constant-array-builder.cc b/deps/v8/src/interpreter/constant-array-builder.cc new file mode 100644 index 0000000000..2586e1ff4d --- /dev/null +++ b/deps/v8/src/interpreter/constant-array-builder.cc @@ -0,0 +1,174 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/interpreter/constant-array-builder.h" + +#include "src/isolate.h" +#include "src/objects-inl.h" + +namespace v8 { +namespace internal { +namespace interpreter { + +ConstantArrayBuilder::ConstantArraySlice::ConstantArraySlice(Zone* zone, + size_t start_index, + size_t capacity) + : start_index_(start_index), + capacity_(capacity), + reserved_(0), + constants_(zone) {} + + +void ConstantArrayBuilder::ConstantArraySlice::Reserve() { + DCHECK_GT(available(), 0u); + reserved_++; + DCHECK_LE(reserved_, capacity() - constants_.size()); +} + + +void ConstantArrayBuilder::ConstantArraySlice::Unreserve() { + DCHECK_GT(reserved_, 0u); + reserved_--; +} + + +size_t ConstantArrayBuilder::ConstantArraySlice::Allocate( + Handle<Object> object) { + DCHECK_GT(available(), 0u); + size_t index = constants_.size(); + DCHECK_LT(index, capacity()); + constants_.push_back(object); + return index + start_index(); +} + + +Handle<Object> ConstantArrayBuilder::ConstantArraySlice::At( + size_t index) const { + return constants_[index - start_index()]; +} + + +STATIC_CONST_MEMBER_DEFINITION const size_t ConstantArrayBuilder::kMaxCapacity; +STATIC_CONST_MEMBER_DEFINITION const size_t ConstantArrayBuilder::kLowCapacity; + + +ConstantArrayBuilder::ConstantArrayBuilder(Isolate* isolate, Zone* zone) + : isolate_(isolate), + idx8_slice_(zone, 0, kLowCapacity), + idx16_slice_(zone, kLowCapacity, kHighCapacity), + constants_map_(isolate->heap(), zone) { + STATIC_ASSERT(kMaxCapacity == static_cast<size_t>(kMaxUInt16 + 1)); + DCHECK_EQ(idx8_slice_.start_index(), 0u); + DCHECK_EQ(idx8_slice_.capacity(), kLowCapacity); + DCHECK_EQ(idx16_slice_.start_index(), kLowCapacity); + DCHECK_EQ(idx16_slice_.capacity(), kMaxCapacity - kLowCapacity); +} + + +size_t ConstantArrayBuilder::size() const { + if (idx16_slice_.size() > 0) { + return idx16_slice_.start_index() + idx16_slice_.size(); + } else { + return idx8_slice_.size(); + } +} + + +Handle<Object> ConstantArrayBuilder::At(size_t index) const { + if (index >= idx16_slice_.start_index()) { + return idx16_slice_.At(index); + } else if (index < idx8_slice_.size()) { + return idx8_slice_.At(index); + } else { + return isolate_->factory()->the_hole_value(); + } +} + + +Handle<FixedArray> ConstantArrayBuilder::ToFixedArray(Factory* factory) const { + Handle<FixedArray> fixed_array = + factory->NewFixedArray(static_cast<int>(size()), PretenureFlag::TENURED); + for (int i = 0; i < fixed_array->length(); i++) { + fixed_array->set(i, *At(static_cast<size_t>(i))); + } + return fixed_array; +} + + +size_t ConstantArrayBuilder::Insert(Handle<Object> object) { + index_t* entry = constants_map_.Find(object); + return (entry == nullptr) ? AllocateEntry(object) : *entry; +} + + +ConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateEntry( + Handle<Object> object) { + DCHECK(!object->IsOddball()); + size_t index; + index_t* entry = constants_map_.Get(object); + if (idx8_slice_.available() > 0) { + index = idx8_slice_.Allocate(object); + } else { + index = idx16_slice_.Allocate(object); + } + CHECK_LT(index, kMaxCapacity); + *entry = static_cast<index_t>(index); + return *entry; +} + + +OperandSize ConstantArrayBuilder::CreateReservedEntry() { + if (idx8_slice_.available() > 0) { + idx8_slice_.Reserve(); + return OperandSize::kByte; + } else if (idx16_slice_.available() > 0) { + idx16_slice_.Reserve(); + return OperandSize::kShort; + } else { + UNREACHABLE(); + return OperandSize::kNone; + } +} + + +size_t ConstantArrayBuilder::CommitReservedEntry(OperandSize operand_size, + Handle<Object> object) { + DiscardReservedEntry(operand_size); + size_t index; + index_t* entry = constants_map_.Find(object); + if (nullptr == entry) { + index = AllocateEntry(object); + } else { + if (operand_size == OperandSize::kByte && + *entry >= idx8_slice_.capacity()) { + // The object is already in the constant array, but has an index + // outside the range of an idx8 operand so we need to create a + // duplicate entry in the idx8 operand range to satisfy the + // commitment. + *entry = static_cast<index_t>(idx8_slice_.Allocate(object)); + } + index = *entry; + } + DCHECK(operand_size == OperandSize::kShort || index < idx8_slice_.capacity()); + DCHECK_LT(index, kMaxCapacity); + return index; +} + + +void ConstantArrayBuilder::DiscardReservedEntry(OperandSize operand_size) { + switch (operand_size) { + case OperandSize::kByte: + idx8_slice_.Unreserve(); + return; + case OperandSize::kShort: + idx16_slice_.Unreserve(); + return; + default: + UNREACHABLE(); + } +} + +} // namespace interpreter +} // namespace internal +} // namespace v8 |