Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 6 | 6 |
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 __ b(ne, &new_object); | 322 __ b(ne, &new_object); |
| 323 | 323 |
| 324 // 5. Allocate a JSValue wrapper for the number. | 324 // 5. Allocate a JSValue wrapper for the number. |
| 325 __ AllocateJSValue(r0, r1, r2, r4, r5, &new_object); | 325 __ AllocateJSValue(r0, r1, r2, r4, r5, &new_object); |
| 326 __ Ret(); | 326 __ Ret(); |
| 327 | 327 |
| 328 // 6. Fallback to the runtime to create new object. | 328 // 6. Fallback to the runtime to create new object. |
| 329 __ bind(&new_object); | 329 __ bind(&new_object); |
| 330 { | 330 { |
| 331 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 331 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 332 __ Push(r2, r1, r3); // first argument, constructor, new target | 332 __ Push(r2); // first argument |
| 333 __ CallRuntime(Runtime::kNewObject); | 333 FastNewObjectStub stub(masm->isolate()); |
| 334 __ CallStub(&stub); | |
| 334 __ Pop(r2); | 335 __ Pop(r2); |
| 335 } | 336 } |
| 336 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); | 337 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); |
| 337 __ Ret(); | 338 __ Ret(); |
| 338 } | 339 } |
| 339 | 340 |
| 340 | 341 |
| 341 // static | 342 // static |
| 342 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 343 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
| 343 // ----------- S t a t e ------------- | 344 // ----------- S t a t e ------------- |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 __ b(ne, &new_object); | 448 __ b(ne, &new_object); |
| 448 | 449 |
| 449 // 5. Allocate a JSValue wrapper for the string. | 450 // 5. Allocate a JSValue wrapper for the string. |
| 450 __ AllocateJSValue(r0, r1, r2, r4, r5, &new_object); | 451 __ AllocateJSValue(r0, r1, r2, r4, r5, &new_object); |
| 451 __ Ret(); | 452 __ Ret(); |
| 452 | 453 |
| 453 // 6. Fallback to the runtime to create new object. | 454 // 6. Fallback to the runtime to create new object. |
| 454 __ bind(&new_object); | 455 __ bind(&new_object); |
| 455 { | 456 { |
| 456 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 457 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 457 __ Push(r2, r1, r3); // first argument, constructor, new target | 458 __ Push(r2); // first argument |
| 458 __ CallRuntime(Runtime::kNewObject); | 459 FastNewObjectStub stub(masm->isolate()); |
| 460 __ CallStub(&stub); | |
| 459 __ Pop(r2); | 461 __ Pop(r2); |
| 460 } | 462 } |
| 461 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); | 463 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); |
| 462 __ Ret(); | 464 __ Ret(); |
| 463 } | 465 } |
| 464 | 466 |
| 465 | 467 |
| 466 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 468 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
| 467 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 469 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 468 __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset)); | 470 __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset)); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 534 // ----------------------------------- | 536 // ----------------------------------- |
| 535 | 537 |
| 536 Isolate* isolate = masm->isolate(); | 538 Isolate* isolate = masm->isolate(); |
| 537 | 539 |
| 538 // Enter a construct frame. | 540 // Enter a construct frame. |
| 539 { | 541 { |
| 540 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); | 542 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); |
| 541 | 543 |
| 542 // Preserve the incoming parameters on the stack. | 544 // Preserve the incoming parameters on the stack. |
| 543 __ AssertUndefinedOrAllocationSite(r2, r4); | 545 __ AssertUndefinedOrAllocationSite(r2, r4); |
| 544 __ push(r2); | |
| 545 __ SmiTag(r0); | 546 __ SmiTag(r0); |
| 546 __ push(r0); | 547 __ Push(r2, r0); |
| 547 | 548 |
| 548 if (create_implicit_receiver) { | 549 if (create_implicit_receiver) { |
| 549 // Try to allocate the object without transitioning into C code. If any of | 550 // Allocate the new receiver object. |
| 550 // the preconditions is not met, the code bails out to the runtime call. | |
| 551 Label rt_call, allocated; | |
| 552 if (FLAG_inline_new) { | |
|
Yang
2016/02/19 06:51:08
do we still care about this flag?
Benedikt Meurer
2016/02/19 06:54:05
I suppose yes, but this already handled in the Mac
| |
| 553 // Verify that the new target is a JSFunction. | |
| 554 __ CompareObjectType(r3, r5, r4, JS_FUNCTION_TYPE); | |
| 555 __ b(ne, &rt_call); | |
| 556 | |
| 557 // Load the initial map and verify that it is in fact a map. | |
| 558 // r3: new target | |
| 559 __ ldr(r2, | |
| 560 FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset)); | |
| 561 __ JumpIfSmi(r2, &rt_call); | |
| 562 __ CompareObjectType(r2, r5, r4, MAP_TYPE); | |
| 563 __ b(ne, &rt_call); | |
| 564 | |
| 565 // Fall back to runtime if the expected base constructor and base | |
| 566 // constructor differ. | |
| 567 __ ldr(r5, FieldMemOperand(r2, Map::kConstructorOrBackPointerOffset)); | |
| 568 __ cmp(r1, r5); | |
| 569 __ b(ne, &rt_call); | |
| 570 | |
| 571 // Check that the constructor is not constructing a JSFunction (see | |
| 572 // comments in Runtime_NewObject in runtime.cc). In which case the | |
| 573 // initial map's instance type would be JS_FUNCTION_TYPE. | |
| 574 // r1: constructor function | |
| 575 // r2: initial map | |
| 576 // r3: new target | |
| 577 __ CompareInstanceType(r2, r5, JS_FUNCTION_TYPE); | |
| 578 __ b(eq, &rt_call); | |
| 579 | |
| 580 // Now allocate the JSObject on the heap. | |
| 581 // r1: constructor function | |
| 582 // r2: initial map | |
| 583 // r3: new target | |
| 584 __ ldrb(r9, FieldMemOperand(r2, Map::kInstanceSizeOffset)); | |
| 585 | |
| 586 __ Allocate(r9, r4, r9, r6, &rt_call, SIZE_IN_WORDS); | |
| 587 | |
| 588 // Allocated the JSObject, now initialize the fields. Map is set to | |
| 589 // initial map and properties and elements are set to empty fixed array. | |
| 590 // r1: constructor function | |
| 591 // r2: initial map | |
| 592 // r3: new target | |
| 593 // r4: JSObject (not HeapObject tagged - the actual address). | |
| 594 // r9: start of next object | |
| 595 __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex); | |
| 596 __ mov(r5, r4); | |
| 597 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset); | |
| 598 __ str(r2, MemOperand(r5, kPointerSize, PostIndex)); | |
| 599 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset); | |
| 600 __ str(r6, MemOperand(r5, kPointerSize, PostIndex)); | |
| 601 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset); | |
| 602 __ str(r6, MemOperand(r5, kPointerSize, PostIndex)); | |
| 603 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize); | |
| 604 | |
| 605 // Add the object tag to make the JSObject real, so that we can continue | |
| 606 // and jump into the continuation code at any time from now on. | |
| 607 __ add(r4, r4, Operand(kHeapObjectTag)); | |
| 608 | |
| 609 // Fill all the in-object properties with the appropriate filler. | |
| 610 // r4: JSObject (tagged) | |
| 611 // r5: First in-object property of JSObject (not tagged) | |
| 612 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); | |
| 613 | |
| 614 if (!is_api_function) { | |
| 615 Label no_inobject_slack_tracking; | |
| 616 | |
| 617 // Check if slack tracking is enabled. | |
| 618 MemOperand bit_field3 = FieldMemOperand(r2, Map::kBitField3Offset); | |
| 619 // Check if slack tracking is enabled. | |
| 620 __ ldr(r0, bit_field3); | |
| 621 __ DecodeField<Map::ConstructionCounter>(ip, r0); | |
| 622 // ip: slack tracking counter | |
| 623 __ cmp(ip, Operand(Map::kSlackTrackingCounterEnd)); | |
| 624 __ b(lt, &no_inobject_slack_tracking); | |
| 625 __ push(ip); // Save allocation count value. | |
| 626 // Decrease generous allocation count. | |
| 627 __ sub(r0, r0, Operand(1 << Map::ConstructionCounter::kShift)); | |
| 628 __ str(r0, bit_field3); | |
| 629 | |
| 630 // Allocate object with a slack. | |
| 631 __ ldr(r0, FieldMemOperand(r2, Map::kInstanceAttributesOffset)); | |
| 632 __ Ubfx(r0, r0, Map::kUnusedPropertyFieldsByte * kBitsPerByte, | |
| 633 kBitsPerByte); | |
| 634 __ sub(r0, r9, Operand(r0, LSL, kPointerSizeLog2)); | |
| 635 // r0: offset of first field after pre-allocated fields | |
| 636 if (FLAG_debug_code) { | |
| 637 __ cmp(r5, r0); | |
| 638 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); | |
| 639 } | |
| 640 __ InitializeFieldsWithFiller(r5, r0, r6); | |
| 641 | |
| 642 // To allow truncation fill the remaining fields with one pointer | |
| 643 // filler map. | |
| 644 __ LoadRoot(r6, Heap::kOnePointerFillerMapRootIndex); | |
| 645 __ InitializeFieldsWithFiller(r5, r9, r6); | |
| 646 | |
| 647 __ pop(r0); // Restore allocation count value before decreasing. | |
| 648 __ cmp(r0, Operand(Map::kSlackTrackingCounterEnd)); | |
| 649 __ b(ne, &allocated); | |
| 650 | |
| 651 // Push the constructor, new_target and the object to the stack, | |
| 652 // and then the initial map as an argument to the runtime call. | |
| 653 __ Push(r1, r3, r4, r2); | |
| 654 __ CallRuntime(Runtime::kFinalizeInstanceSize); | |
| 655 __ Pop(r1, r3, r4); | |
| 656 | |
| 657 // Continue with JSObject being successfully allocated | |
| 658 // r1: constructor function | |
| 659 // r3: new target | |
| 660 // r4: JSObject | |
| 661 __ jmp(&allocated); | |
| 662 | |
| 663 __ bind(&no_inobject_slack_tracking); | |
| 664 } | |
| 665 | |
| 666 __ InitializeFieldsWithFiller(r5, r9, r6); | |
| 667 | |
| 668 // Continue with JSObject being successfully allocated | |
| 669 // r1: constructor function | |
| 670 // r3: new target | |
| 671 // r4: JSObject | |
| 672 __ jmp(&allocated); | |
| 673 } | |
| 674 | |
| 675 // Allocate the new receiver object using the runtime call. | |
| 676 // r1: constructor function | |
| 677 // r3: new target | |
| 678 __ bind(&rt_call); | |
| 679 | |
| 680 // Push the constructor and new_target twice, second pair as arguments | |
| 681 // to the runtime call. | |
| 682 __ Push(r1, r3); | 551 __ Push(r1, r3); |
| 683 __ Push(r1, r3); // constructor function, new target | 552 FastNewObjectStub stub(masm->isolate()); |
| 684 __ CallRuntime(Runtime::kNewObject); | 553 __ CallStub(&stub); |
| 685 __ mov(r4, r0); | 554 __ mov(r4, r0); |
| 686 __ Pop(r1, r3); | 555 __ Pop(r1, r3); |
| 687 | 556 |
| 688 // Receiver for constructor call allocated. | 557 // ----------- S t a t e ------------- |
| 689 // r1: constructor function | 558 // -- r1: constructor function |
| 690 // r3: new target | 559 // -- r3: new target |
| 691 // r4: JSObject | 560 // -- r4: newly allocated object |
| 692 __ bind(&allocated); | 561 // ----------------------------------- |
| 693 | 562 |
| 694 // Retrieve smi-tagged arguments count from the stack. | 563 // Retrieve smi-tagged arguments count from the stack. |
| 695 __ ldr(r0, MemOperand(sp)); | 564 __ ldr(r0, MemOperand(sp)); |
| 696 } | 565 } |
| 697 | 566 |
| 698 __ SmiUntag(r0); | 567 __ SmiUntag(r0); |
| 699 | 568 |
| 700 if (create_implicit_receiver) { | 569 if (create_implicit_receiver) { |
| 701 // Push the allocated receiver to the stack. We need two copies | 570 // Push the allocated receiver to the stack. We need two copies |
| 702 // because we may have to return the original one and the calling | 571 // because we may have to return the original one and the calling |
| (...skipping 1987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2690 } | 2559 } |
| 2691 } | 2560 } |
| 2692 | 2561 |
| 2693 | 2562 |
| 2694 #undef __ | 2563 #undef __ |
| 2695 | 2564 |
| 2696 } // namespace internal | 2565 } // namespace internal |
| 2697 } // namespace v8 | 2566 } // namespace v8 |
| 2698 | 2567 |
| 2699 #endif // V8_TARGET_ARCH_ARM | 2568 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |