OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 124 |
125 | 125 |
126 static Failure* ThrowArrayLengthRangeError(Heap* heap) { | 126 static Failure* ThrowArrayLengthRangeError(Heap* heap) { |
127 HandleScope scope(heap->isolate()); | 127 HandleScope scope(heap->isolate()); |
128 return heap->isolate()->Throw( | 128 return heap->isolate()->Throw( |
129 *heap->isolate()->factory()->NewRangeError("invalid_array_length", | 129 *heap->isolate()->factory()->NewRangeError("invalid_array_length", |
130 HandleVector<Object>(NULL, 0))); | 130 HandleVector<Object>(NULL, 0))); |
131 } | 131 } |
132 | 132 |
133 | 133 |
134 void CopyObjectToObjectElements(AssertNoAllocation* no_gc, | 134 void CopyObjectToObjectElements(FixedArray* from, |
135 FixedArray* from_obj, | |
136 ElementsKind from_kind, | 135 ElementsKind from_kind, |
137 uint32_t from_start, | 136 uint32_t from_start, |
138 FixedArray* to_obj, | 137 FixedArray* to, |
139 ElementsKind to_kind, | 138 ElementsKind to_kind, |
140 uint32_t to_start, | 139 uint32_t to_start, |
141 int copy_size) { | 140 int raw_copy_size, |
142 ASSERT(to_obj->map() != HEAP->fixed_cow_array_map()); | 141 WriteBarrierMode mode) { |
| 142 ASSERT(to->map() != HEAP->fixed_cow_array_map()); |
143 ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS); | 143 ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS); |
144 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); | 144 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); |
145 if (copy_size == -1) { | 145 int copy_size = raw_copy_size; |
146 copy_size = Min(from_obj->length() - from_start, | 146 if (raw_copy_size < 0) { |
147 to_obj->length() - to_start); | 147 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 148 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 149 copy_size = Min(from->length() - from_start, |
| 150 to->length() - to_start); |
| 151 #ifdef DEBUG |
| 152 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already |
| 153 // marked with the hole. |
| 154 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 155 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 156 ASSERT(to->get(i)->IsTheHole()); |
| 157 } |
| 158 } |
| 159 #endif |
148 } | 160 } |
149 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() && | 161 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
150 (copy_size + static_cast<int>(from_start)) <= from_obj->length())); | 162 (copy_size + static_cast<int>(from_start)) <= from->length()); |
151 if (copy_size == 0) return; | 163 if (copy_size == 0) return; |
152 Address to = to_obj->address() + FixedArray::kHeaderSize; | 164 Address to_address = to->address() + FixedArray::kHeaderSize; |
153 Address from = from_obj->address() + FixedArray::kHeaderSize; | 165 Address from_address = from->address() + FixedArray::kHeaderSize; |
154 CopyWords(reinterpret_cast<Object**>(to) + to_start, | 166 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, |
155 reinterpret_cast<Object**>(from) + from_start, | 167 reinterpret_cast<Object**>(from_address) + from_start, |
156 copy_size); | 168 copy_size); |
157 if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) { | 169 if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS && |
158 Heap* heap = from_obj->GetHeap(); | 170 mode == UPDATE_WRITE_BARRIER) { |
159 WriteBarrierMode mode = to_obj->GetWriteBarrierMode(*no_gc); | 171 Heap* heap = from->GetHeap(); |
160 if (mode == UPDATE_WRITE_BARRIER) { | 172 if (!heap->InNewSpace(to)) { |
161 heap->RecordWrites(to_obj->address(), | 173 heap->RecordWrites(to->address(), |
162 to_obj->OffsetOfElementAt(to_start), | 174 to->OffsetOfElementAt(to_start), |
163 copy_size); | 175 copy_size); |
164 } | 176 } |
165 heap->incremental_marking()->RecordWrites(to_obj); | 177 heap->incremental_marking()->RecordWrites(to); |
166 } | 178 } |
167 } | 179 } |
168 | 180 |
169 | 181 |
170 | |
171 | |
172 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, | 182 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, |
173 uint32_t from_start, | 183 uint32_t from_start, |
174 FixedArray* to, | 184 FixedArray* to, |
175 ElementsKind to_kind, | 185 ElementsKind to_kind, |
176 uint32_t to_start, | 186 uint32_t to_start, |
177 int copy_size) { | 187 int raw_copy_size, |
| 188 WriteBarrierMode mode) { |
| 189 int copy_size = raw_copy_size; |
| 190 Heap* heap = from->GetHeap(); |
| 191 if (raw_copy_size < 0) { |
| 192 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 193 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 194 copy_size = from->max_number_key() + 1 - from_start; |
| 195 #ifdef DEBUG |
| 196 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already |
| 197 // marked with the hole. |
| 198 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 199 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 200 ASSERT(to->get(i)->IsTheHole()); |
| 201 } |
| 202 } |
| 203 #endif |
| 204 } |
| 205 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length()); |
178 ASSERT(to != from); | 206 ASSERT(to != from); |
179 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); | 207 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); |
180 ASSERT(copy_size == -1 || | 208 if (copy_size == 0) return; |
181 (copy_size + static_cast<int>(to_start)) <= to->length()); | 209 for (int i = 0; i < copy_size; i++) { |
182 WriteBarrierMode mode = to_kind == FAST_ELEMENTS | 210 int entry = from->FindEntry(i + from_start); |
183 ? UPDATE_WRITE_BARRIER | 211 if (entry != SeededNumberDictionary::kNotFound) { |
184 : SKIP_WRITE_BARRIER; | 212 Object* value = from->ValueAt(entry); |
185 uint32_t copy_limit = (copy_size == -1) | 213 ASSERT(!value->IsTheHole()); |
186 ? to->length() | 214 to->set(i + to_start, value, SKIP_WRITE_BARRIER); |
187 : Min(to_start + copy_size, static_cast<uint32_t>(to->length())); | 215 } else { |
188 for (int i = 0; i < from->Capacity(); ++i) { | 216 to->set_the_hole(i + to_start); |
189 Object* key = from->KeyAt(i); | |
190 if (key->IsNumber()) { | |
191 uint32_t entry = static_cast<uint32_t>(key->Number()); | |
192 if (entry >= to_start && entry < copy_limit) { | |
193 Object* value = from->ValueAt(i); | |
194 ASSERT(to_kind == FAST_ELEMENTS || value->IsSmi()); | |
195 to->set(entry, value, mode); | |
196 } | |
197 } | 217 } |
198 } | 218 } |
| 219 if (to_kind == FAST_ELEMENTS) { |
| 220 if (!heap->InNewSpace(to)) { |
| 221 heap->RecordWrites(to->address(), |
| 222 to->OffsetOfElementAt(to_start), |
| 223 copy_size); |
| 224 } |
| 225 heap->incremental_marking()->RecordWrites(to); |
| 226 } |
199 } | 227 } |
200 | 228 |
201 | 229 |
202 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( | 230 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
203 FixedDoubleArray* from_obj, | 231 FixedDoubleArray* from, |
204 uint32_t from_start, | 232 uint32_t from_start, |
205 FixedArray* to_obj, | 233 FixedArray* to, |
206 ElementsKind to_kind, | 234 ElementsKind to_kind, |
207 uint32_t to_start, | 235 uint32_t to_start, |
208 int copy_size) { | 236 int raw_copy_size) { |
209 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); | 237 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); |
210 if (copy_size == -1) { | 238 int copy_size = raw_copy_size; |
211 copy_size = Min(from_obj->length() - from_start, | 239 if (raw_copy_size < 0) { |
212 to_obj->length() - to_start); | 240 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 241 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 242 copy_size = Min(from->length() - from_start, |
| 243 to->length() - to_start); |
| 244 #ifdef DEBUG |
| 245 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already |
| 246 // marked with the hole. |
| 247 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 248 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 249 ASSERT(to->get(i)->IsTheHole()); |
| 250 } |
| 251 } |
| 252 #endif |
213 } | 253 } |
214 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() && | 254 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
215 (copy_size + static_cast<int>(from_start)) <= from_obj->length())); | 255 (copy_size + static_cast<int>(from_start)) <= from->length()); |
216 if (copy_size == 0) return from_obj; | 256 if (copy_size == 0) return from; |
217 for (int i = 0; i < copy_size; ++i) { | 257 for (int i = 0; i < copy_size; ++i) { |
218 if (to_kind == FAST_SMI_ONLY_ELEMENTS) { | 258 if (to_kind == FAST_SMI_ONLY_ELEMENTS) { |
219 UNIMPLEMENTED(); | 259 UNIMPLEMENTED(); |
220 return Failure::Exception(); | 260 return Failure::Exception(); |
221 } else { | 261 } else { |
222 MaybeObject* maybe_value = from_obj->get(i + from_start); | 262 MaybeObject* maybe_value = from->get(i + from_start); |
223 Object* value; | 263 Object* value; |
224 ASSERT(to_kind == FAST_ELEMENTS); | 264 ASSERT(to_kind == FAST_ELEMENTS); |
225 // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects | 265 // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects |
226 // iteratively, the allocate must succeed within a single GC cycle, | 266 // iteratively, the allocate must succeed within a single GC cycle, |
227 // otherwise the retry after the GC will also fail. In order to ensure | 267 // otherwise the retry after the GC will also fail. In order to ensure |
228 // that no GC is triggered, allocate HeapNumbers from old space if they | 268 // that no GC is triggered, allocate HeapNumbers from old space if they |
229 // can't be taken from new space. | 269 // can't be taken from new space. |
230 if (!maybe_value->ToObject(&value)) { | 270 if (!maybe_value->ToObject(&value)) { |
231 ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); | 271 ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); |
232 Heap* heap = from_obj->GetHeap(); | 272 Heap* heap = from->GetHeap(); |
233 MaybeObject* maybe_value_object = | 273 MaybeObject* maybe_value_object = |
234 heap->AllocateHeapNumber(from_obj->get_scalar(i + from_start), | 274 heap->AllocateHeapNumber(from->get_scalar(i + from_start), |
235 TENURED); | 275 TENURED); |
236 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; | 276 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; |
237 } | 277 } |
238 to_obj->set(i + to_start, value, UPDATE_WRITE_BARRIER); | 278 to->set(i + to_start, value, UPDATE_WRITE_BARRIER); |
239 } | 279 } |
240 } | 280 } |
241 return to_obj; | 281 return to; |
242 } | 282 } |
243 | 283 |
244 | 284 |
245 static void CopyDoubleToDoubleElements(FixedDoubleArray* from_obj, | 285 static void CopyDoubleToDoubleElements(FixedDoubleArray* from, |
246 uint32_t from_start, | 286 uint32_t from_start, |
247 FixedDoubleArray* to_obj, | 287 FixedDoubleArray* to, |
248 uint32_t to_start, | 288 uint32_t to_start, |
249 int copy_size) { | 289 int raw_copy_size) { |
250 if (copy_size == -1) { | 290 int copy_size = raw_copy_size; |
251 copy_size = Min(from_obj->length() - from_start, | 291 if (raw_copy_size < 0) { |
252 to_obj->length() - to_start); | 292 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 293 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 294 copy_size = Min(from->length() - from_start, |
| 295 to->length() - to_start); |
| 296 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 297 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 298 to->set_the_hole(i); |
| 299 } |
| 300 } |
253 } | 301 } |
254 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() && | 302 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
255 (copy_size + static_cast<int>(from_start)) <= from_obj->length())); | 303 (copy_size + static_cast<int>(from_start)) <= from->length()); |
256 if (copy_size == 0) return; | 304 if (copy_size == 0) return; |
257 Address to = to_obj->address() + FixedDoubleArray::kHeaderSize; | 305 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; |
258 Address from = from_obj->address() + FixedDoubleArray::kHeaderSize; | 306 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; |
259 to += kDoubleSize * to_start; | 307 to_address += kDoubleSize * to_start; |
260 from += kDoubleSize * from_start; | 308 from_address += kDoubleSize * from_start; |
261 int words_per_double = (kDoubleSize / kPointerSize); | 309 int words_per_double = (kDoubleSize / kPointerSize); |
262 CopyWords(reinterpret_cast<Object**>(to), | 310 CopyWords(reinterpret_cast<Object**>(to_address), |
263 reinterpret_cast<Object**>(from), | 311 reinterpret_cast<Object**>(from_address), |
264 words_per_double * copy_size); | 312 words_per_double * copy_size); |
265 } | 313 } |
266 | 314 |
267 | 315 |
| 316 static void CopyObjectToDoubleElements(FixedArray* from, |
| 317 uint32_t from_start, |
| 318 FixedDoubleArray* to, |
| 319 uint32_t to_start, |
| 320 int raw_copy_size) { |
| 321 int copy_size = raw_copy_size; |
| 322 if (raw_copy_size < 0) { |
| 323 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 324 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 325 copy_size = from->length() - from_start; |
| 326 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 327 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 328 to->set_the_hole(i); |
| 329 } |
| 330 } |
| 331 } |
| 332 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
| 333 (copy_size + static_cast<int>(from_start)) <= from->length()); |
| 334 if (copy_size == 0) return; |
| 335 for (int i = 0; i < copy_size; i++) { |
| 336 Object* hole_or_object = from->get(i + from_start); |
| 337 if (hole_or_object->IsTheHole()) { |
| 338 to->set_the_hole(i + to_start); |
| 339 } else { |
| 340 to->set(i + to_start, hole_or_object->Number()); |
| 341 } |
| 342 } |
| 343 } |
| 344 |
| 345 |
| 346 static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from, |
| 347 uint32_t from_start, |
| 348 FixedDoubleArray* to, |
| 349 uint32_t to_start, |
| 350 int raw_copy_size) { |
| 351 int copy_size = raw_copy_size; |
| 352 if (copy_size < 0) { |
| 353 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || |
| 354 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 355 copy_size = from->max_number_key() + 1 - from_start; |
| 356 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 357 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 358 to->set_the_hole(i); |
| 359 } |
| 360 } |
| 361 } |
| 362 ASSERT(copy_size + static_cast<int>(to_start) <= to->length()); |
| 363 if (copy_size == 0) return; |
| 364 for (int i = 0; i < copy_size; i++) { |
| 365 int entry = from->FindEntry(i + from_start); |
| 366 if (entry != SeededNumberDictionary::kNotFound) { |
| 367 to->set(i + to_start, from->ValueAt(entry)->Number()); |
| 368 } else { |
| 369 to->set_the_hole(i + to_start); |
| 370 } |
| 371 } |
| 372 } |
| 373 |
| 374 |
268 // Base class for element handler implementations. Contains the | 375 // Base class for element handler implementations. Contains the |
269 // the common logic for objects with different ElementsKinds. | 376 // the common logic for objects with different ElementsKinds. |
270 // Subclasses must specialize method for which the element | 377 // Subclasses must specialize method for which the element |
271 // implementation differs from the base class implementation. | 378 // implementation differs from the base class implementation. |
272 // | 379 // |
273 // This class is intended to be used in the following way: | 380 // This class is intended to be used in the following way: |
274 // | 381 // |
275 // class SomeElementsAccessor : | 382 // class SomeElementsAccessor : |
276 // public ElementsAccessorBase<SomeElementsAccessor, | 383 // public ElementsAccessorBase<SomeElementsAccessor, |
277 // BackingStoreClass> { | 384 // BackingStoreClass> { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 | 469 |
363 virtual MaybeObject* Delete(JSObject* obj, | 470 virtual MaybeObject* Delete(JSObject* obj, |
364 uint32_t key, | 471 uint32_t key, |
365 JSReceiver::DeleteMode mode) = 0; | 472 JSReceiver::DeleteMode mode) = 0; |
366 | 473 |
367 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 474 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
368 uint32_t from_start, | 475 uint32_t from_start, |
369 FixedArrayBase* to, | 476 FixedArrayBase* to, |
370 ElementsKind to_kind, | 477 ElementsKind to_kind, |
371 uint32_t to_start, | 478 uint32_t to_start, |
372 int copy_size) { | 479 int copy_size, |
| 480 WriteBarrierMode mode) { |
373 UNREACHABLE(); | 481 UNREACHABLE(); |
374 return NULL; | 482 return NULL; |
375 } | 483 } |
376 | 484 |
377 virtual MaybeObject* CopyElements(JSObject* from_holder, | 485 virtual MaybeObject* CopyElements(JSObject* from_holder, |
378 uint32_t from_start, | 486 uint32_t from_start, |
379 FixedArrayBase* to, | 487 FixedArrayBase* to, |
380 ElementsKind to_kind, | 488 ElementsKind to_kind, |
381 uint32_t to_start, | 489 uint32_t to_start, |
382 int copy_size, | 490 int copy_size, |
| 491 WriteBarrierMode mode, |
383 FixedArrayBase* from) { | 492 FixedArrayBase* from) { |
384 if (from == NULL) { | 493 if (from == NULL) { |
385 from = from_holder->elements(); | 494 from = from_holder->elements(); |
386 } | 495 } |
| 496 if (from->length() == 0) { |
| 497 return from; |
| 498 } |
387 return ElementsAccessorSubclass::CopyElementsImpl( | 499 return ElementsAccessorSubclass::CopyElementsImpl( |
388 from, from_start, to, to_kind, to_start, copy_size); | 500 from, from_start, to, to_kind, to_start, copy_size, mode); |
389 } | 501 } |
390 | 502 |
391 virtual MaybeObject* AddElementsToFixedArray(Object* receiver, | 503 virtual MaybeObject* AddElementsToFixedArray(Object* receiver, |
392 JSObject* holder, | 504 JSObject* holder, |
393 FixedArray* to, | 505 FixedArray* to, |
394 FixedArrayBase* from) { | 506 FixedArrayBase* from) { |
395 int len0 = to->length(); | 507 int len0 = to->length(); |
396 #ifdef DEBUG | 508 #ifdef DEBUG |
397 if (FLAG_enable_slow_asserts) { | 509 if (FLAG_enable_slow_asserts) { |
398 for (int i = 0; i < len0; i++) { | 510 for (int i = 0; i < len0; i++) { |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 } | 727 } |
616 } | 728 } |
617 return heap->true_value(); | 729 return heap->true_value(); |
618 } | 730 } |
619 | 731 |
620 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 732 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
621 uint32_t from_start, | 733 uint32_t from_start, |
622 FixedArrayBase* to, | 734 FixedArrayBase* to, |
623 ElementsKind to_kind, | 735 ElementsKind to_kind, |
624 uint32_t to_start, | 736 uint32_t to_start, |
625 int copy_size) { | 737 int copy_size, |
| 738 WriteBarrierMode mode) { |
626 switch (to_kind) { | 739 switch (to_kind) { |
627 case FAST_SMI_ONLY_ELEMENTS: | 740 case FAST_SMI_ONLY_ELEMENTS: |
628 case FAST_ELEMENTS: { | 741 case FAST_ELEMENTS: { |
629 AssertNoAllocation no_gc; | |
630 CopyObjectToObjectElements( | 742 CopyObjectToObjectElements( |
631 &no_gc, FixedArray::cast(from), ElementsTraits::Kind, from_start, | 743 FixedArray::cast(from), ElementsTraits::Kind, from_start, |
632 FixedArray::cast(to), to_kind, to_start, copy_size); | 744 FixedArray::cast(to), to_kind, to_start, copy_size, mode); |
633 return from; | 745 return from; |
634 } | 746 } |
| 747 case FAST_DOUBLE_ELEMENTS: |
| 748 CopyObjectToDoubleElements( |
| 749 FixedArray::cast(from), from_start, |
| 750 FixedDoubleArray::cast(to), to_start, copy_size); |
| 751 return from; |
635 default: | 752 default: |
636 UNREACHABLE(); | 753 UNREACHABLE(); |
637 } | 754 } |
638 return to->GetHeap()->undefined_value(); | 755 return to->GetHeap()->undefined_value(); |
639 } | 756 } |
640 | 757 |
641 | 758 |
642 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, | 759 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, |
643 uint32_t capacity, | 760 uint32_t capacity, |
644 uint32_t length) { | 761 uint32_t length) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >; | 802 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >; |
686 friend class FastElementsAccessor<FastDoubleElementsAccessor, | 803 friend class FastElementsAccessor<FastDoubleElementsAccessor, |
687 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, | 804 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, |
688 kDoubleSize>; | 805 kDoubleSize>; |
689 | 806 |
690 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 807 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
691 uint32_t from_start, | 808 uint32_t from_start, |
692 FixedArrayBase* to, | 809 FixedArrayBase* to, |
693 ElementsKind to_kind, | 810 ElementsKind to_kind, |
694 uint32_t to_start, | 811 uint32_t to_start, |
695 int copy_size) { | 812 int copy_size, |
| 813 WriteBarrierMode mode) { |
696 switch (to_kind) { | 814 switch (to_kind) { |
697 case FAST_SMI_ONLY_ELEMENTS: | 815 case FAST_SMI_ONLY_ELEMENTS: |
698 case FAST_ELEMENTS: | 816 case FAST_ELEMENTS: |
699 return CopyDoubleToObjectElements( | 817 return CopyDoubleToObjectElements( |
700 FixedDoubleArray::cast(from), from_start, FixedArray::cast(to), | 818 FixedDoubleArray::cast(from), from_start, FixedArray::cast(to), |
701 to_kind, to_start, copy_size); | 819 to_kind, to_start, copy_size); |
702 case FAST_DOUBLE_ELEMENTS: | 820 case FAST_DOUBLE_ELEMENTS: |
703 CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start, | 821 CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start, |
704 FixedDoubleArray::cast(to), | 822 FixedDoubleArray::cast(to), |
705 to_start, copy_size); | 823 to_start, copy_size); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 } | 1100 } |
983 } | 1101 } |
984 return heap->true_value(); | 1102 return heap->true_value(); |
985 } | 1103 } |
986 | 1104 |
987 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1105 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
988 uint32_t from_start, | 1106 uint32_t from_start, |
989 FixedArrayBase* to, | 1107 FixedArrayBase* to, |
990 ElementsKind to_kind, | 1108 ElementsKind to_kind, |
991 uint32_t to_start, | 1109 uint32_t to_start, |
992 int copy_size) { | 1110 int copy_size, |
| 1111 WriteBarrierMode mode) { |
993 switch (to_kind) { | 1112 switch (to_kind) { |
994 case FAST_SMI_ONLY_ELEMENTS: | 1113 case FAST_SMI_ONLY_ELEMENTS: |
995 case FAST_ELEMENTS: | 1114 case FAST_ELEMENTS: |
996 CopyDictionaryToObjectElements( | 1115 CopyDictionaryToObjectElements( |
997 SeededNumberDictionary::cast(from), from_start, | 1116 SeededNumberDictionary::cast(from), from_start, |
998 FixedArray::cast(to), to_kind, to_start, copy_size); | 1117 FixedArray::cast(to), to_kind, to_start, copy_size, mode); |
| 1118 return from; |
| 1119 case FAST_DOUBLE_ELEMENTS: |
| 1120 CopyDictionaryToDoubleElements( |
| 1121 SeededNumberDictionary::cast(from), from_start, |
| 1122 FixedDoubleArray::cast(to), to_start, copy_size); |
999 return from; | 1123 return from; |
1000 default: | 1124 default: |
1001 UNREACHABLE(); | 1125 UNREACHABLE(); |
1002 } | 1126 } |
1003 return to->GetHeap()->undefined_value(); | 1127 return to->GetHeap()->undefined_value(); |
1004 } | 1128 } |
1005 | 1129 |
1006 | 1130 |
1007 protected: | 1131 protected: |
1008 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 1132 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 } | 1245 } |
1122 } | 1246 } |
1123 return obj->GetHeap()->true_value(); | 1247 return obj->GetHeap()->true_value(); |
1124 } | 1248 } |
1125 | 1249 |
1126 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1250 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
1127 uint32_t from_start, | 1251 uint32_t from_start, |
1128 FixedArrayBase* to, | 1252 FixedArrayBase* to, |
1129 ElementsKind to_kind, | 1253 ElementsKind to_kind, |
1130 uint32_t to_start, | 1254 uint32_t to_start, |
1131 int copy_size) { | 1255 int copy_size, |
| 1256 WriteBarrierMode mode) { |
1132 FixedArray* parameter_map = FixedArray::cast(from); | 1257 FixedArray* parameter_map = FixedArray::cast(from); |
1133 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1258 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
1134 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 1259 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
1135 return accessor->CopyElements(NULL, from_start, to, to_kind, | 1260 return accessor->CopyElements(NULL, from_start, to, to_kind, |
1136 to_start, copy_size, arguments); | 1261 to_start, copy_size, mode, arguments); |
1137 } | 1262 } |
1138 | 1263 |
1139 static uint32_t GetCapacityImpl(FixedArray* parameter_map) { | 1264 static uint32_t GetCapacityImpl(FixedArray* parameter_map) { |
1140 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1265 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
1141 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1266 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
1142 ForArray(arguments)->GetCapacity(arguments)); | 1267 ForArray(arguments)->GetCapacity(arguments)); |
1143 } | 1268 } |
1144 | 1269 |
1145 static uint32_t GetKeyForIndexImpl(FixedArray* dict, | 1270 static uint32_t GetKeyForIndexImpl(FixedArray* dict, |
1146 uint32_t index) { | 1271 uint32_t index) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; | 1412 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; |
1288 new_backing_store->set(0, length); | 1413 new_backing_store->set(0, length); |
1289 { MaybeObject* result = array->SetContent(new_backing_store); | 1414 { MaybeObject* result = array->SetContent(new_backing_store); |
1290 if (result->IsFailure()) return result; | 1415 if (result->IsFailure()) return result; |
1291 } | 1416 } |
1292 return array; | 1417 return array; |
1293 } | 1418 } |
1294 | 1419 |
1295 | 1420 |
1296 } } // namespace v8::internal | 1421 } } // namespace v8::internal |
OLD | NEW |