OLD | NEW |
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 <set> | 7 #include <set> |
8 | 8 |
9 #include "src/isolate.h" | 9 #include "src/isolate.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 return true; | 64 return true; |
65 } | 65 } |
66 | 66 |
67 STATIC_CONST_MEMBER_DEFINITION const size_t ConstantArrayBuilder::k8BitCapacity; | 67 STATIC_CONST_MEMBER_DEFINITION const size_t ConstantArrayBuilder::k8BitCapacity; |
68 STATIC_CONST_MEMBER_DEFINITION const size_t | 68 STATIC_CONST_MEMBER_DEFINITION const size_t |
69 ConstantArrayBuilder::k16BitCapacity; | 69 ConstantArrayBuilder::k16BitCapacity; |
70 STATIC_CONST_MEMBER_DEFINITION const size_t | 70 STATIC_CONST_MEMBER_DEFINITION const size_t |
71 ConstantArrayBuilder::k32BitCapacity; | 71 ConstantArrayBuilder::k32BitCapacity; |
72 | 72 |
73 ConstantArrayBuilder::ConstantArrayBuilder(Isolate* isolate, Zone* zone) | 73 ConstantArrayBuilder::ConstantArrayBuilder(Isolate* isolate, Zone* zone) |
74 : isolate_(isolate), constants_map_(zone) { | 74 : isolate_(isolate), |
| 75 constants_map_(zone), |
| 76 smi_map_(zone), |
| 77 smi_pairs_(zone) { |
75 idx_slice_[0] = | 78 idx_slice_[0] = |
76 new (zone) ConstantArraySlice(zone, 0, k8BitCapacity, OperandSize::kByte); | 79 new (zone) ConstantArraySlice(zone, 0, k8BitCapacity, OperandSize::kByte); |
77 idx_slice_[1] = new (zone) ConstantArraySlice( | 80 idx_slice_[1] = new (zone) ConstantArraySlice( |
78 zone, k8BitCapacity, k16BitCapacity, OperandSize::kShort); | 81 zone, k8BitCapacity, k16BitCapacity, OperandSize::kShort); |
79 idx_slice_[2] = new (zone) ConstantArraySlice( | 82 idx_slice_[2] = new (zone) ConstantArraySlice( |
80 zone, k8BitCapacity + k16BitCapacity, k32BitCapacity, OperandSize::kQuad); | 83 zone, k8BitCapacity + k16BitCapacity, k32BitCapacity, OperandSize::kQuad); |
81 } | 84 } |
82 | 85 |
83 size_t ConstantArrayBuilder::size() const { | 86 size_t ConstantArrayBuilder::size() const { |
84 size_t i = arraysize(idx_slice_); | 87 size_t i = arraysize(idx_slice_); |
(...skipping 21 matching lines...) Expand all Loading... |
106 const ConstantArraySlice* slice = IndexToSlice(index); | 109 const ConstantArraySlice* slice = IndexToSlice(index); |
107 if (index < slice->start_index() + slice->size()) { | 110 if (index < slice->start_index() + slice->size()) { |
108 return slice->At(index); | 111 return slice->At(index); |
109 } else { | 112 } else { |
110 DCHECK_LT(index, slice->capacity()); | 113 DCHECK_LT(index, slice->capacity()); |
111 return isolate_->factory()->the_hole_value(); | 114 return isolate_->factory()->the_hole_value(); |
112 } | 115 } |
113 } | 116 } |
114 | 117 |
115 Handle<FixedArray> ConstantArrayBuilder::ToFixedArray() { | 118 Handle<FixedArray> ConstantArrayBuilder::ToFixedArray() { |
| 119 // First insert reserved SMI values. |
| 120 for (auto reserved_smi : smi_pairs_) { |
| 121 InsertAllocatedEntry(reserved_smi.second, |
| 122 handle(reserved_smi.first, isolate_)); |
| 123 } |
| 124 |
116 Handle<FixedArray> fixed_array = isolate_->factory()->NewFixedArray( | 125 Handle<FixedArray> fixed_array = isolate_->factory()->NewFixedArray( |
117 static_cast<int>(size()), PretenureFlag::TENURED); | 126 static_cast<int>(size()), PretenureFlag::TENURED); |
118 int array_index = 0; | 127 int array_index = 0; |
119 for (const ConstantArraySlice* slice : idx_slice_) { | 128 for (const ConstantArraySlice* slice : idx_slice_) { |
120 if (array_index == fixed_array->length()) { | 129 if (array_index == fixed_array->length()) { |
121 break; | 130 break; |
122 } | 131 } |
123 DCHECK(array_index == 0 || | 132 DCHECK(array_index == 0 || |
124 base::bits::IsPowerOfTwo32(static_cast<uint32_t>(array_index))); | 133 base::bits::IsPowerOfTwo32(static_cast<uint32_t>(array_index))); |
125 // Different slices might contain the same element due to reservations, but | 134 // Different slices might contain the same element due to reservations, but |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 for (size_t i = 0; i < arraysize(idx_slice_); ++i) { | 211 for (size_t i = 0; i < arraysize(idx_slice_); ++i) { |
203 if (idx_slice_[i]->available() > 0) { | 212 if (idx_slice_[i]->available() > 0) { |
204 idx_slice_[i]->Reserve(); | 213 idx_slice_[i]->Reserve(); |
205 return idx_slice_[i]->operand_size(); | 214 return idx_slice_[i]->operand_size(); |
206 } | 215 } |
207 } | 216 } |
208 UNREACHABLE(); | 217 UNREACHABLE(); |
209 return OperandSize::kNone; | 218 return OperandSize::kNone; |
210 } | 219 } |
211 | 220 |
| 221 ConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateReservedEntry( |
| 222 Smi* value) { |
| 223 index_t index = static_cast<index_t>(AllocateEntry()); |
| 224 smi_map_[value] = index; |
| 225 smi_pairs_.push_back(std::make_pair(value, index)); |
| 226 return index; |
| 227 } |
| 228 |
212 size_t ConstantArrayBuilder::CommitReservedEntry(OperandSize operand_size, | 229 size_t ConstantArrayBuilder::CommitReservedEntry(OperandSize operand_size, |
213 Handle<Object> object) { | 230 Smi* value) { |
214 DiscardReservedEntry(operand_size); | 231 DiscardReservedEntry(operand_size); |
215 size_t index; | 232 size_t index; |
216 auto entry = constants_map_.find(object.address()); | 233 auto entry = smi_map_.find(value); |
217 if (entry == constants_map_.end()) { | 234 if (entry == smi_map_.end()) { |
218 index = AllocateEntry(object); | 235 index = AllocateReservedEntry(value); |
219 } else { | 236 } else { |
220 ConstantArraySlice* slice = OperandSizeToSlice(operand_size); | 237 ConstantArraySlice* slice = OperandSizeToSlice(operand_size); |
221 index = entry->second; | 238 index = entry->second; |
222 if (index > slice->max_index()) { | 239 if (index > slice->max_index()) { |
223 // The object is already in the constant array, but may have an | 240 // The object is already in the constant array, but may have an |
224 // index too big for the reserved operand_size. So, duplicate | 241 // index too big for the reserved operand_size. So, duplicate |
225 // entry with the smaller operand size. | 242 // entry with the smaller operand size. |
226 index = slice->Allocate(object); | 243 index = AllocateReservedEntry(value); |
227 constants_map_[object.address()] = static_cast<index_t>(index); | |
228 } | 244 } |
| 245 DCHECK_LE(index, slice->max_index()); |
229 } | 246 } |
230 return index; | 247 return index; |
231 } | 248 } |
232 | 249 |
233 void ConstantArrayBuilder::DiscardReservedEntry(OperandSize operand_size) { | 250 void ConstantArrayBuilder::DiscardReservedEntry(OperandSize operand_size) { |
234 OperandSizeToSlice(operand_size)->Unreserve(); | 251 OperandSizeToSlice(operand_size)->Unreserve(); |
235 } | 252 } |
236 | 253 |
237 } // namespace interpreter | 254 } // namespace interpreter |
238 } // namespace internal | 255 } // namespace internal |
239 } // namespace v8 | 256 } // namespace v8 |
OLD | NEW |