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

Side by Side Diff: src/arm64/builtins-arm64.cc

Issue 1708313002: [stubs] Introduce a dedicated FastNewObjectStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove TODO. Created 4 years, 10 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
OLDNEW
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 #if V8_TARGET_ARCH_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/arm64/frames-arm64.h" 7 #include "src/arm64/frames-arm64.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/debug/debug.h" 9 #include "src/debug/debug.h"
10 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 __ B(ne, &new_object); 313 __ B(ne, &new_object);
314 314
315 // 5. Allocate a JSValue wrapper for the number. 315 // 5. Allocate a JSValue wrapper for the number.
316 __ AllocateJSValue(x0, x1, x2, x4, x5, &new_object); 316 __ AllocateJSValue(x0, x1, x2, x4, x5, &new_object);
317 __ Ret(); 317 __ Ret();
318 318
319 // 6. Fallback to the runtime to create new object. 319 // 6. Fallback to the runtime to create new object.
320 __ bind(&new_object); 320 __ bind(&new_object);
321 { 321 {
322 FrameScope scope(masm, StackFrame::INTERNAL); 322 FrameScope scope(masm, StackFrame::INTERNAL);
323 __ Push(x2, x1, x3); // first argument, constructor, new target 323 __ Push(x2); // first argument
324 __ CallRuntime(Runtime::kNewObject); 324 FastNewObjectStub stub(masm->isolate());
325 __ CallStub(&stub);
325 __ Pop(x2); 326 __ Pop(x2);
326 } 327 }
327 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); 328 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset));
328 __ Ret(); 329 __ Ret();
329 } 330 }
330 331
331 332
332 // static 333 // static
333 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { 334 void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
334 // ----------- S t a t e ------------- 335 // ----------- S t a t e -------------
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 __ B(ne, &new_object); 441 __ B(ne, &new_object);
441 442
442 // 5. Allocate a JSValue wrapper for the string. 443 // 5. Allocate a JSValue wrapper for the string.
443 __ AllocateJSValue(x0, x1, x2, x4, x5, &new_object); 444 __ AllocateJSValue(x0, x1, x2, x4, x5, &new_object);
444 __ Ret(); 445 __ Ret();
445 446
446 // 6. Fallback to the runtime to create new object. 447 // 6. Fallback to the runtime to create new object.
447 __ bind(&new_object); 448 __ bind(&new_object);
448 { 449 {
449 FrameScope scope(masm, StackFrame::INTERNAL); 450 FrameScope scope(masm, StackFrame::INTERNAL);
450 __ Push(x2, x1, x3); // first argument, constructor, new target 451 __ Push(x2); // first argument
451 __ CallRuntime(Runtime::kNewObject); 452 FastNewObjectStub stub(masm->isolate());
453 __ CallStub(&stub);
452 __ Pop(x2); 454 __ Pop(x2);
453 } 455 }
454 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); 456 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset));
455 __ Ret(); 457 __ Ret();
456 } 458 }
457 459
458 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { 460 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
459 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); 461 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
460 __ Ldr(x2, FieldMemOperand(x2, SharedFunctionInfo::kCodeOffset)); 462 __ Ldr(x2, FieldMemOperand(x2, SharedFunctionInfo::kCodeOffset));
461 __ Add(x2, x2, Code::kHeaderSize - kHeapObjectTag); 463 __ Add(x2, x2, Code::kHeaderSize - kHeapObjectTag);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 Register constructor = x1; 534 Register constructor = x1;
533 Register allocation_site = x2; 535 Register allocation_site = x2;
534 Register new_target = x3; 536 Register new_target = x3;
535 537
536 // Preserve the incoming parameters on the stack. 538 // Preserve the incoming parameters on the stack.
537 __ AssertUndefinedOrAllocationSite(allocation_site, x10); 539 __ AssertUndefinedOrAllocationSite(allocation_site, x10);
538 __ SmiTag(argc); 540 __ SmiTag(argc);
539 __ Push(allocation_site, argc); 541 __ Push(allocation_site, argc);
540 542
541 if (create_implicit_receiver) { 543 if (create_implicit_receiver) {
542 // sp[0]: new.target 544 // Allocate the new receiver object.
543 // sp[1]: Constructor function. 545 __ Push(constructor, new_target);
544 // sp[2]: number of arguments (smi-tagged) 546 FastNewObjectStub stub(masm->isolate());
545 // sp[3]: allocation site 547 __ CallStub(&stub);
546 // Try to allocate the object without transitioning into C code. If any of
547 // the preconditions is not met, the code bails out to the runtime call.
548 Label rt_call, allocated;
549 if (FLAG_inline_new) {
550 // Verify that the new target is a JSFunction.
551 __ JumpIfNotObjectType(new_target, x10, x11, JS_FUNCTION_TYPE,
552 &rt_call);
553
554 // Load the initial map and verify that it is in fact a map.
555 Register init_map = x2;
556 __ Ldr(init_map,
557 FieldMemOperand(new_target,
558 JSFunction::kPrototypeOrInitialMapOffset));
559 __ JumpIfSmi(init_map, &rt_call);
560 __ JumpIfNotObjectType(init_map, x10, x11, MAP_TYPE, &rt_call);
561
562 // Fall back to runtime if the expected base constructor and base
563 // constructor differ.
564 __ Ldr(x10,
565 FieldMemOperand(init_map, Map::kConstructorOrBackPointerOffset));
566 __ Cmp(constructor, x10);
567 __ B(ne, &rt_call);
568
569 // Check that the constructor is not constructing a JSFunction (see
570 // comments in Runtime_NewObject in runtime.cc). In which case the
571 // initial
572 // map's instance type would be JS_FUNCTION_TYPE.
573 __ CompareInstanceType(init_map, x10, JS_FUNCTION_TYPE);
574 __ B(eq, &rt_call);
575
576 // Now allocate the JSObject on the heap.
577 Register obj_size = x10;
578 Register new_obj = x4;
579 Register next_obj = obj_size; // May overlap.
580 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset));
581 __ Allocate(obj_size, new_obj, next_obj, x11, &rt_call, SIZE_IN_WORDS);
582
583 // Allocated the JSObject, now initialize the fields. Map is set to
584 // initial map and properties and elements are set to empty fixed array.
585 // NB. the object pointer is not tagged, so MemOperand is used.
586 Register write_address = x5;
587 Register empty = x7;
588 __ Mov(write_address, new_obj);
589 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
590 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset);
591 __ Str(init_map, MemOperand(write_address, kPointerSize, PostIndex));
592 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset);
593 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset);
594 __ Stp(empty, empty,
595 MemOperand(write_address, 2 * kPointerSize, PostIndex));
596 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize);
597
598 // Add the object tag to make the JSObject real, so that we can continue
599 // and jump into the continuation code at any time from now on.
600 __ Add(new_obj, new_obj, kHeapObjectTag);
601
602 // Fill all of the in-object properties with the appropriate filler.
603 Register filler = x7;
604 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex);
605
606 if (!is_api_function) {
607 Label no_inobject_slack_tracking;
608
609 Register constructon_count = x14;
610 MemOperand bit_field3 =
611 FieldMemOperand(init_map, Map::kBitField3Offset);
612 // Check if slack tracking is enabled.
613 __ Ldr(x11, bit_field3);
614 __ DecodeField<Map::ConstructionCounter>(constructon_count, x11);
615 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd));
616 __ B(lt, &no_inobject_slack_tracking);
617 // Decrease generous allocation count.
618 __ Subs(x11, x11, Operand(1 << Map::ConstructionCounter::kShift));
619 __ Str(x11, bit_field3);
620
621 // Allocate object with a slack.
622 Register unused_props = x11;
623 __ Ldr(unused_props,
624 FieldMemOperand(init_map, Map::kInstanceAttributesOffset));
625 __ Ubfx(unused_props, unused_props,
626 Map::kUnusedPropertyFieldsByte * kBitsPerByte, kBitsPerByte);
627
628 Register end_of_pre_allocated = x11;
629 __ Sub(end_of_pre_allocated, next_obj,
630 Operand(unused_props, LSL, kPointerSizeLog2));
631 unused_props = NoReg;
632
633 if (FLAG_debug_code) {
634 __ Cmp(write_address, end_of_pre_allocated);
635 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
636 }
637
638 // Fill the pre-allocated fields with undef.
639 __ InitializeFieldsWithFiller(write_address, end_of_pre_allocated,
640 filler);
641
642 // Fill the remaining fields with one pointer filler map.
643 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex);
644 __ InitializeFieldsWithFiller(write_address, next_obj, filler);
645
646 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd));
647 __ B(ne, &allocated);
648
649 // Push the constructor, new_target and the object to the stack,
650 // and then the initial map as an argument to the runtime call.
651 __ Push(constructor, new_target, new_obj, init_map);
652 __ CallRuntime(Runtime::kFinalizeInstanceSize);
653 __ Pop(new_obj, new_target, constructor);
654
655 // Continue with JSObject being successfully allocated.
656 __ B(&allocated);
657
658 __ bind(&no_inobject_slack_tracking);
659 }
660
661 __ InitializeFieldsWithFiller(write_address, next_obj, filler);
662
663 // Continue with JSObject being successfully allocated.
664 __ B(&allocated);
665 }
666
667 // Allocate the new receiver object using the runtime call.
668 // x1: constructor function
669 // x3: new target
670 __ Bind(&rt_call);
671
672 // Push the constructor and new_target twice, second pair as arguments
673 // to the runtime call.
674 __ Push(constructor, new_target, constructor, new_target);
675 __ CallRuntime(Runtime::kNewObject);
676 __ Mov(x4, x0); 548 __ Mov(x4, x0);
677 __ Pop(new_target, constructor); 549 __ Pop(new_target, constructor);
678 550
679 // Receiver for constructor call allocated. 551 // ----------- S t a t e -------------
680 // x1: constructor function 552 // -- x1: constructor function
681 // x3: new target 553 // -- x3: new target
682 // x4: JSObject 554 // -- x4: newly allocated object
683 __ Bind(&allocated); 555 // -----------------------------------
684 556
685 // Reload the number of arguments from the stack. 557 // Reload the number of arguments from the stack.
686 // Set it up in x0 for the function call below. 558 // Set it up in x0 for the function call below.
687 // jssp[0]: number of arguments (smi-tagged) 559 // jssp[0]: number of arguments (smi-tagged)
688 __ Peek(argc, 0); // Load number of arguments. 560 __ Peek(argc, 0); // Load number of arguments.
689 } 561 }
690 562
691 __ SmiUntag(argc); 563 __ SmiUntag(argc);
692 564
693 if (create_implicit_receiver) { 565 if (create_implicit_receiver) {
(...skipping 2129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2823 } 2695 }
2824 } 2696 }
2825 2697
2826 2698
2827 #undef __ 2699 #undef __
2828 2700
2829 } // namespace internal 2701 } // namespace internal
2830 } // namespace v8 2702 } // namespace v8
2831 2703
2832 #endif // V8_TARGET_ARCH_ARM 2704 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698