Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: src/interpreter/constant-array-builder.cc

Issue 1731893003: [interpreter] Preparation for 32-bit operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Compilation fix. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/constant-array-builder.h ('k') | src/utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/constant-array-builder.h" 5 #include "src/interpreter/constant-array-builder.h"
6 6
7 #include "src/isolate.h" 7 #include "src/isolate.h"
8 #include "src/objects-inl.h" 8 #include "src/objects-inl.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 namespace interpreter { 12 namespace interpreter {
13 13
14 ConstantArrayBuilder::ConstantArraySlice::ConstantArraySlice(Zone* zone, 14 ConstantArrayBuilder::ConstantArraySlice::ConstantArraySlice(
15 size_t start_index, 15 Zone* zone, size_t start_index, size_t capacity, OperandSize operand_size)
16 size_t capacity)
17 : start_index_(start_index), 16 : start_index_(start_index),
18 capacity_(capacity), 17 capacity_(capacity),
19 reserved_(0), 18 reserved_(0),
19 operand_size_(operand_size),
20 constants_(zone) {} 20 constants_(zone) {}
21 21
22
23 void ConstantArrayBuilder::ConstantArraySlice::Reserve() { 22 void ConstantArrayBuilder::ConstantArraySlice::Reserve() {
24 DCHECK_GT(available(), 0u); 23 DCHECK_GT(available(), 0u);
25 reserved_++; 24 reserved_++;
26 DCHECK_LE(reserved_, capacity() - constants_.size()); 25 DCHECK_LE(reserved_, capacity() - constants_.size());
27 } 26 }
28 27
29
30 void ConstantArrayBuilder::ConstantArraySlice::Unreserve() { 28 void ConstantArrayBuilder::ConstantArraySlice::Unreserve() {
31 DCHECK_GT(reserved_, 0u); 29 DCHECK_GT(reserved_, 0u);
32 reserved_--; 30 reserved_--;
33 } 31 }
34 32
35
36 size_t ConstantArrayBuilder::ConstantArraySlice::Allocate( 33 size_t ConstantArrayBuilder::ConstantArraySlice::Allocate(
37 Handle<Object> object) { 34 Handle<Object> object) {
38 DCHECK_GT(available(), 0u); 35 DCHECK_GT(available(), 0u);
39 size_t index = constants_.size(); 36 size_t index = constants_.size();
40 DCHECK_LT(index, capacity()); 37 DCHECK_LT(index, capacity());
41 constants_.push_back(object); 38 constants_.push_back(object);
42 return index + start_index(); 39 return index + start_index();
43 } 40 }
44 41
45
46 Handle<Object> ConstantArrayBuilder::ConstantArraySlice::At( 42 Handle<Object> ConstantArrayBuilder::ConstantArraySlice::At(
47 size_t index) const { 43 size_t index) const {
44 DCHECK_GE(index, start_index());
45 DCHECK_LT(index, start_index() + size());
48 return constants_[index - start_index()]; 46 return constants_[index - start_index()];
49 } 47 }
50 48
51 49 STATIC_CONST_MEMBER_DEFINITION const size_t ConstantArrayBuilder::k8BitCapacity;
52 STATIC_CONST_MEMBER_DEFINITION const size_t ConstantArrayBuilder::kMaxCapacity; 50 STATIC_CONST_MEMBER_DEFINITION const size_t
53 STATIC_CONST_MEMBER_DEFINITION const size_t ConstantArrayBuilder::kLowCapacity; 51 ConstantArrayBuilder::k16BitCapacity;
54 52 STATIC_CONST_MEMBER_DEFINITION const size_t
53 ConstantArrayBuilder::k32BitCapacity;
55 54
56 ConstantArrayBuilder::ConstantArrayBuilder(Isolate* isolate, Zone* zone) 55 ConstantArrayBuilder::ConstantArrayBuilder(Isolate* isolate, Zone* zone)
57 : isolate_(isolate), 56 : isolate_(isolate), constants_map_(isolate->heap(), zone) {
58 idx8_slice_(zone, 0, kLowCapacity), 57 idx_slice_[0] =
59 idx16_slice_(zone, kLowCapacity, kHighCapacity), 58 new (zone) ConstantArraySlice(zone, 0, k8BitCapacity, OperandSize::kByte);
60 constants_map_(isolate->heap(), zone) { 59 idx_slice_[1] = new (zone) ConstantArraySlice(
61 STATIC_ASSERT(kMaxCapacity == static_cast<size_t>(kMaxUInt16 + 1)); 60 zone, k8BitCapacity, k16BitCapacity, OperandSize::kShort);
62 DCHECK_EQ(idx8_slice_.start_index(), 0u);
63 DCHECK_EQ(idx8_slice_.capacity(), kLowCapacity);
64 DCHECK_EQ(idx16_slice_.start_index(), kLowCapacity);
65 DCHECK_EQ(idx16_slice_.capacity(), kMaxCapacity - kLowCapacity);
66 } 61 }
67 62
68
69 size_t ConstantArrayBuilder::size() const { 63 size_t ConstantArrayBuilder::size() const {
70 if (idx16_slice_.size() > 0) { 64 size_t i = arraysize(idx_slice_);
71 return idx16_slice_.start_index() + idx16_slice_.size(); 65 while (i > 0) {
72 } else { 66 ConstantArraySlice* slice = idx_slice_[--i];
73 return idx8_slice_.size(); 67 if (slice->size() > 0) {
68 return slice->start_index() + slice->size();
69 }
74 } 70 }
71 return idx_slice_[0]->size();
75 } 72 }
76 73
74 ConstantArrayBuilder::ConstantArraySlice* ConstantArrayBuilder::IndexToSlice(
rmcilroy 2016/02/25 13:26:06 This seems a bit overkill to me. I'd prefer just t
oth 2016/02/25 15:40:15 Compensated in ToFixedArray to avoid 2-3x penalty
75 size_t index) const {
76 DCHECK_LE(index, kMaxUInt32);
77 static const int kLog2Table[] = {0, 1, 2, 2};
78 int clz = base::bits::CountLeadingZeros32(static_cast<uint32_t>(index | 1));
79 int byte_index = (31 - clz) >> 3;
80 return idx_slice_[kLog2Table[byte_index]];
81 }
77 82
78 Handle<Object> ConstantArrayBuilder::At(size_t index) const { 83 Handle<Object> ConstantArrayBuilder::At(size_t index) const {
79 if (index >= idx16_slice_.start_index()) { 84 ConstantArraySlice* slice = IndexToSlice(index);
80 return idx16_slice_.At(index); 85 if (index < slice->start_index() + slice->size()) {
81 } else if (index < idx8_slice_.size()) { 86 return slice->At(index);
82 return idx8_slice_.At(index);
83 } else { 87 } else {
84 return isolate_->factory()->the_hole_value(); 88 return isolate_->factory()->the_hole_value();
85 } 89 }
86 } 90 }
87 91
88 Handle<FixedArray> ConstantArrayBuilder::ToFixedArray() { 92 Handle<FixedArray> ConstantArrayBuilder::ToFixedArray() {
89 Handle<FixedArray> fixed_array = isolate_->factory()->NewFixedArray( 93 Handle<FixedArray> fixed_array = isolate_->factory()->NewFixedArray(
90 static_cast<int>(size()), PretenureFlag::TENURED); 94 static_cast<int>(size()), PretenureFlag::TENURED);
91 for (int i = 0; i < fixed_array->length(); i++) { 95 for (int i = 0; i < fixed_array->length(); i++) {
92 fixed_array->set(i, *At(static_cast<size_t>(i))); 96 fixed_array->set(i, *At(static_cast<size_t>(i)));
93 } 97 }
94 constants_map()->Clear(); 98 constants_map()->Clear();
95 return fixed_array; 99 return fixed_array;
96 } 100 }
97 101
98
99 size_t ConstantArrayBuilder::Insert(Handle<Object> object) { 102 size_t ConstantArrayBuilder::Insert(Handle<Object> object) {
100 index_t* entry = constants_map()->Find(object); 103 index_t* entry = constants_map()->Find(object);
101 return (entry == nullptr) ? AllocateEntry(object) : *entry; 104 return (entry == nullptr) ? AllocateEntry(object) : *entry;
102 } 105 }
103 106
104
105 ConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateEntry( 107 ConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateEntry(
106 Handle<Object> object) { 108 Handle<Object> object) {
107 DCHECK(!object->IsOddball()); 109 DCHECK(!object->IsOddball());
108 size_t index; 110 size_t index;
rmcilroy 2016/02/25 13:26:06 nit - move this into the for loop now
oth 2016/02/25 15:40:15 Done.
109 index_t* entry = constants_map()->Get(object); 111 index_t* entry = constants_map()->Get(object);
110 if (idx8_slice_.available() > 0) { 112 for (size_t i = 0; i < arraysize(idx_slice_); ++i) {
111 index = idx8_slice_.Allocate(object); 113 if (idx_slice_[i]->available() > 0) {
112 } else { 114 index = idx_slice_[i]->Allocate(object);
113 index = idx16_slice_.Allocate(object); 115 *entry = static_cast<index_t>(index);
116 return *entry;
117 break;
118 }
114 } 119 }
115 CHECK_LT(index, kMaxCapacity); 120 UNREACHABLE();
116 *entry = static_cast<index_t>(index); 121 return kMaxUInt32;
117 return *entry;
118 } 122 }
119 123
120
121 OperandSize ConstantArrayBuilder::CreateReservedEntry() { 124 OperandSize ConstantArrayBuilder::CreateReservedEntry() {
122 if (idx8_slice_.available() > 0) { 125 for (size_t i = 0; i < arraysize(idx_slice_); ++i) {
123 idx8_slice_.Reserve(); 126 if (idx_slice_[i]->available() > 0) {
124 return OperandSize::kByte; 127 idx_slice_[i]->Reserve();
125 } else if (idx16_slice_.available() > 0) { 128 return idx_slice_[i]->operand_size();
126 idx16_slice_.Reserve(); 129 }
127 return OperandSize::kShort;
128 } else {
129 UNREACHABLE();
130 return OperandSize::kNone;
131 } 130 }
131 UNREACHABLE();
132 return OperandSize::kNone;
132 } 133 }
133 134
134
135 size_t ConstantArrayBuilder::CommitReservedEntry(OperandSize operand_size, 135 size_t ConstantArrayBuilder::CommitReservedEntry(OperandSize operand_size,
136 Handle<Object> object) { 136 Handle<Object> object) {
137 DiscardReservedEntry(operand_size); 137 DiscardReservedEntry(operand_size);
138 size_t index; 138 size_t index;
139 index_t* entry = constants_map()->Find(object); 139 index_t* entry = constants_map()->Find(object);
140 if (nullptr == entry) { 140 if (nullptr == entry) {
141 index = AllocateEntry(object); 141 index = AllocateEntry(object);
142 } else { 142 } else {
143 if (operand_size == OperandSize::kByte && 143 // The object is already in the constant array, but may have an
rmcilroy 2016/02/25 13:26:06 Could you pull the check for entry in a larger ope
oth 2016/02/25 15:40:15 Done.
144 *entry >= idx8_slice_.capacity()) { 144 // index too big for the reserved operand_size. So, duplicate
145 // The object is already in the constant array, but has an index 145 // entry with the smaller operand size.
146 // outside the range of an idx8 operand so we need to create a 146 for (size_t i = arraysize(idx_slice_); i > 0; --i) {
147 // duplicate entry in the idx8 operand range to satisfy the 147 ConstantArraySlice* slice = idx_slice_[i - 1];
148 // commitment. 148 if (operand_size == slice->operand_size() &&
149 *entry = static_cast<index_t>(idx8_slice_.Allocate(object)); 149 *entry > slice->max_index()) {
150 *entry = static_cast<index_t>(slice->Allocate(object));
151 break;
152 }
150 } 153 }
151 index = *entry; 154 index = *entry;
152 } 155 }
153 DCHECK(operand_size == OperandSize::kShort || index < idx8_slice_.capacity());
154 DCHECK_LT(index, kMaxCapacity);
155 return index; 156 return index;
156 } 157 }
157 158
158
159 void ConstantArrayBuilder::DiscardReservedEntry(OperandSize operand_size) { 159 void ConstantArrayBuilder::DiscardReservedEntry(OperandSize operand_size) {
160 switch (operand_size) { 160 for (size_t i = 0; i < arraysize(idx_slice_); ++i) {
161 case OperandSize::kByte: 161 if (operand_size == idx_slice_[i]->operand_size()) {
rmcilroy 2016/02/25 13:26:06 Could you make idx_slice_ indexable by operand_siz
oth 2016/02/25 15:40:15 There is existing code already assumes the enum va
162 idx8_slice_.Unreserve(); 162 idx_slice_[i]->Unreserve();
163 return; 163 return;
164 case OperandSize::kShort: 164 }
165 idx16_slice_.Unreserve();
166 return;
167 default:
168 UNREACHABLE();
169 } 165 }
166 UNREACHABLE();
170 } 167 }
171 168
172 } // namespace interpreter 169 } // namespace interpreter
173 } // namespace internal 170 } // namespace internal
174 } // namespace v8 171 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/constant-array-builder.h ('k') | src/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698