OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug.h" | 10 #include "src/debug.h" |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 __ Cmp(constructor, original_constructor); | 372 __ Cmp(constructor, original_constructor); |
373 __ B(eq, &normal_new); | 373 __ B(eq, &normal_new); |
374 Generate_Runtime_NewObject(masm, create_memento, original_constructor, | 374 Generate_Runtime_NewObject(masm, create_memento, original_constructor, |
375 &count_incremented, &allocated); | 375 &count_incremented, &allocated); |
376 | 376 |
377 __ Bind(&normal_new); | 377 __ Bind(&normal_new); |
378 | 378 |
379 // Try to allocate the object without transitioning into C code. If any of | 379 // Try to allocate the object without transitioning into C code. If any of |
380 // the preconditions is not met, the code bails out to the runtime call. | 380 // the preconditions is not met, the code bails out to the runtime call. |
381 if (FLAG_inline_new) { | 381 if (FLAG_inline_new) { |
382 Label undo_allocation; | |
383 ExternalReference debug_step_in_fp = | 382 ExternalReference debug_step_in_fp = |
384 ExternalReference::debug_step_in_fp_address(isolate); | 383 ExternalReference::debug_step_in_fp_address(isolate); |
385 __ Mov(x2, Operand(debug_step_in_fp)); | 384 __ Mov(x2, Operand(debug_step_in_fp)); |
386 __ Ldr(x2, MemOperand(x2)); | 385 __ Ldr(x2, MemOperand(x2)); |
387 __ Cbnz(x2, &rt_call); | 386 __ Cbnz(x2, &rt_call); |
388 // Load the initial map and verify that it is in fact a map. | 387 // Load the initial map and verify that it is in fact a map. |
389 Register init_map = x2; | 388 Register init_map = x2; |
390 __ Ldr(init_map, | 389 __ Ldr(init_map, |
391 FieldMemOperand(constructor, | 390 FieldMemOperand(constructor, |
392 JSFunction::kPrototypeOrInitialMapOffset)); | 391 JSFunction::kPrototypeOrInitialMapOffset)); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 | 447 |
449 Register first_prop = x5; | 448 Register first_prop = x5; |
450 __ Add(first_prop, new_obj, JSObject::kHeaderSize); | 449 __ Add(first_prop, new_obj, JSObject::kHeaderSize); |
451 | 450 |
452 // Fill all of the in-object properties with the appropriate filler. | 451 // Fill all of the in-object properties with the appropriate filler. |
453 Register filler = x7; | 452 Register filler = x7; |
454 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); | 453 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); |
455 | 454 |
456 // Obtain number of pre-allocated property fields and in-object | 455 // Obtain number of pre-allocated property fields and in-object |
457 // properties. | 456 // properties. |
| 457 Register unused_props = x10; |
| 458 Register inobject_props = x11; |
| 459 Register inst_sizes_or_attrs = x11; |
458 Register prealloc_fields = x10; | 460 Register prealloc_fields = x10; |
459 Register inobject_props = x11; | 461 __ Ldr(inst_sizes_or_attrs, |
460 Register inst_sizes = x11; | 462 FieldMemOperand(init_map, Map::kInstanceAttributesOffset)); |
461 __ Ldr(inst_sizes, FieldMemOperand(init_map, Map::kInstanceSizesOffset)); | 463 __ Ubfx(unused_props, inst_sizes_or_attrs, |
462 __ Ubfx(prealloc_fields, inst_sizes, | 464 Map::kUnusedPropertyFieldsByte * kBitsPerByte, kBitsPerByte); |
463 Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, | 465 __ Ldr(inst_sizes_or_attrs, |
464 kBitsPerByte); | 466 FieldMemOperand(init_map, Map::kInstanceSizesOffset)); |
465 __ Ubfx(inobject_props, inst_sizes, | 467 __ Ubfx(inobject_props, inst_sizes_or_attrs, |
466 Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte); | 468 Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte); |
| 469 __ Sub(prealloc_fields, inobject_props, unused_props); |
467 | 470 |
468 // Calculate number of property fields in the object. | 471 // Calculate number of property fields in the object. |
469 Register prop_fields = x6; | 472 Register prop_fields = x6; |
470 __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize); | 473 __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize); |
471 | 474 |
472 if (!is_api_function) { | 475 if (!is_api_function) { |
473 Label no_inobject_slack_tracking; | 476 Label no_inobject_slack_tracking; |
474 | 477 |
475 // Check if slack tracking is enabled. | 478 // Check if slack tracking is enabled. |
476 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | 479 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); | 514 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); |
512 first_prop = NoReg; | 515 first_prop = NoReg; |
513 } else { | 516 } else { |
514 // Fill all of the property fields with undef. | 517 // Fill all of the property fields with undef. |
515 __ FillFields(first_prop, prop_fields, filler); | 518 __ FillFields(first_prop, prop_fields, filler); |
516 first_prop = NoReg; | 519 first_prop = NoReg; |
517 prop_fields = NoReg; | 520 prop_fields = NoReg; |
518 } | 521 } |
519 | 522 |
520 // Add the object tag to make the JSObject real, so that we can continue | 523 // Add the object tag to make the JSObject real, so that we can continue |
521 // and jump into the continuation code at any time from now on. Any | 524 // and jump into the continuation code at any time from now on. |
522 // failures need to undo the allocation, so that the heap is in a | |
523 // consistent state and verifiable. | |
524 __ Add(new_obj, new_obj, kHeapObjectTag); | 525 __ Add(new_obj, new_obj, kHeapObjectTag); |
525 | 526 |
526 // Check if a non-empty properties array is needed. Continue with | |
527 // allocated object if not; allocate and initialize a FixedArray if yes. | |
528 Register element_count = x3; | |
529 __ Ldrb(element_count, | |
530 FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset)); | |
531 // The field instance sizes contains both pre-allocated property fields | |
532 // and in-object properties. | |
533 __ Add(element_count, element_count, prealloc_fields); | |
534 __ Subs(element_count, element_count, inobject_props); | |
535 | |
536 // Done if no extra properties are to be allocated. | |
537 __ B(eq, &allocated); | |
538 __ Assert(pl, kPropertyAllocationCountFailed); | |
539 | |
540 // Scale the number of elements by pointer size and add the header for | |
541 // FixedArrays to the start of the next object calculation from above. | |
542 Register new_array = x5; | |
543 Register array_size = x6; | |
544 __ Add(array_size, element_count, FixedArray::kHeaderSize / kPointerSize); | |
545 __ Allocate(array_size, new_array, x11, x12, &undo_allocation, | |
546 static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | | |
547 SIZE_IN_WORDS)); | |
548 | |
549 Register array_map = x10; | |
550 __ LoadRoot(array_map, Heap::kFixedArrayMapRootIndex); | |
551 __ Str(array_map, MemOperand(new_array, FixedArray::kMapOffset)); | |
552 __ SmiTag(x0, element_count); | |
553 __ Str(x0, MemOperand(new_array, FixedArray::kLengthOffset)); | |
554 | |
555 // Initialize the fields to undefined. | |
556 Register elements = x10; | |
557 __ Add(elements, new_array, FixedArray::kHeaderSize); | |
558 __ FillFields(elements, element_count, filler); | |
559 | |
560 // Store the initialized FixedArray into the properties field of the | |
561 // JSObject. | |
562 __ Add(new_array, new_array, kHeapObjectTag); | |
563 __ Str(new_array, FieldMemOperand(new_obj, JSObject::kPropertiesOffset)); | |
564 | |
565 // Continue with JSObject being successfully allocated. | 527 // Continue with JSObject being successfully allocated. |
566 __ B(&allocated); | 528 __ B(&allocated); |
567 | |
568 // Undo the setting of the new top so that the heap is verifiable. For | |
569 // example, the map's unused properties potentially do not match the | |
570 // allocated objects unused properties. | |
571 __ Bind(&undo_allocation); | |
572 __ UndoAllocationInNewSpace(new_obj, x14); | |
573 } | 529 } |
574 | 530 |
575 // Allocate the new receiver object using the runtime call. | 531 // Allocate the new receiver object using the runtime call. |
576 __ Bind(&rt_call); | 532 __ Bind(&rt_call); |
577 Generate_Runtime_NewObject(masm, create_memento, constructor, | 533 Generate_Runtime_NewObject(masm, create_memento, constructor, |
578 &count_incremented, &allocated); | 534 &count_incremented, &allocated); |
579 | 535 |
580 // Receiver for constructor call allocated. | 536 // Receiver for constructor call allocated. |
581 // x4: JSObject | 537 // x4: JSObject |
582 __ Bind(&allocated); | 538 __ Bind(&allocated); |
(...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1839 } | 1795 } |
1840 } | 1796 } |
1841 | 1797 |
1842 | 1798 |
1843 #undef __ | 1799 #undef __ |
1844 | 1800 |
1845 } // namespace internal | 1801 } // namespace internal |
1846 } // namespace v8 | 1802 } // namespace v8 |
1847 | 1803 |
1848 #endif // V8_TARGET_ARCH_ARM | 1804 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |