summaryrefslogtreecommitdiff
path: root/deps/v8/src/interpreter/constant-array-builder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/interpreter/constant-array-builder.cc')
-rw-r--r--deps/v8/src/interpreter/constant-array-builder.cc174
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