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

Side by Side Diff: src/mips/builtins-mips.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 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_MIPS 5 #if V8_TARGET_ARCH_MIPS
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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 __ Branch(&new_object, ne, a1, Operand(a3)); 326 __ Branch(&new_object, ne, a1, Operand(a3));
327 327
328 // 5. Allocate a JSValue wrapper for the number. 328 // 5. Allocate a JSValue wrapper for the number.
329 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object); 329 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object);
330 __ Ret(); 330 __ Ret();
331 331
332 // 6. Fallback to the runtime to create new object. 332 // 6. Fallback to the runtime to create new object.
333 __ bind(&new_object); 333 __ bind(&new_object);
334 { 334 {
335 FrameScope scope(masm, StackFrame::INTERNAL); 335 FrameScope scope(masm, StackFrame::INTERNAL);
336 __ Push(a0, a1, a3); // first argument, constructor, new target 336 __ Push(a0); // first argument
337 __ CallRuntime(Runtime::kNewObject); 337 FastNewObjectStub stub(masm->isolate());
338 __ CallStub(&stub);
338 __ Pop(a0); 339 __ Pop(a0);
339 } 340 }
340 __ Ret(USE_DELAY_SLOT); 341 __ Ret(USE_DELAY_SLOT);
341 __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot 342 __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot
342 } 343 }
343 344
344 345
345 // static 346 // static
346 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { 347 void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
347 // ----------- S t a t e ------------- 348 // ----------- S t a t e -------------
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 __ Branch(&new_object, ne, a1, Operand(a3)); 455 __ Branch(&new_object, ne, a1, Operand(a3));
455 456
456 // 5. Allocate a JSValue wrapper for the string. 457 // 5. Allocate a JSValue wrapper for the string.
457 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object); 458 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object);
458 __ Ret(); 459 __ Ret();
459 460
460 // 6. Fallback to the runtime to create new object. 461 // 6. Fallback to the runtime to create new object.
461 __ bind(&new_object); 462 __ bind(&new_object);
462 { 463 {
463 FrameScope scope(masm, StackFrame::INTERNAL); 464 FrameScope scope(masm, StackFrame::INTERNAL);
464 __ Push(a0, a1, a3); // first argument, constructor, new target 465 __ Push(a0); // first argument
465 __ CallRuntime(Runtime::kNewObject); 466 FastNewObjectStub stub(masm->isolate());
467 __ CallStub(&stub);
466 __ Pop(a0); 468 __ Pop(a0);
467 } 469 }
468 __ Ret(USE_DELAY_SLOT); 470 __ Ret(USE_DELAY_SLOT);
469 __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot 471 __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot
470 } 472 }
471 473
472 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { 474 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
473 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 475 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
474 __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); 476 __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
475 __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); 477 __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 // Enter a construct frame. 539 // Enter a construct frame.
538 { 540 {
539 FrameScope scope(masm, StackFrame::CONSTRUCT); 541 FrameScope scope(masm, StackFrame::CONSTRUCT);
540 542
541 // Preserve the incoming parameters on the stack. 543 // Preserve the incoming parameters on the stack.
542 __ AssertUndefinedOrAllocationSite(a2, t0); 544 __ AssertUndefinedOrAllocationSite(a2, t0);
543 __ SmiTag(a0); 545 __ SmiTag(a0);
544 __ Push(a2, a0); 546 __ Push(a2, a0);
545 547
546 if (create_implicit_receiver) { 548 if (create_implicit_receiver) {
547 // Try to allocate the object without transitioning into C code. If any of 549 // Allocate the new receiver object.
548 // the preconditions is not met, the code bails out to the runtime call. 550 __ Push(a1, a3);
549 Label rt_call, allocated; 551 FastNewObjectStub stub(masm->isolate());
550 if (FLAG_inline_new) { 552 __ CallStub(&stub);
551 // Verify that the new target is a JSFunction.
552 __ GetObjectType(a3, t1, t0);
553 __ Branch(&rt_call, ne, t0, Operand(JS_FUNCTION_TYPE));
554
555 // Load the initial map and verify that it is in fact a map.
556 // a3: new target
557 __ lw(a2,
558 FieldMemOperand(a3, JSFunction::kPrototypeOrInitialMapOffset));
559 __ JumpIfSmi(a2, &rt_call);
560 __ GetObjectType(a2, t5, t4);
561 __ Branch(&rt_call, ne, t4, Operand(MAP_TYPE));
562
563 // Fall back to runtime if the expected base constructor and base
564 // constructor differ.
565 __ lw(t1, FieldMemOperand(a2, Map::kConstructorOrBackPointerOffset));
566 __ Branch(&rt_call, ne, a1, Operand(t1));
567
568 // Check that the constructor is not constructing a JSFunction (see
569 // comments in Runtime_NewObject in runtime.cc). In which case the
570 // initial map's instance type would be JS_FUNCTION_TYPE.
571 // a1: constructor function
572 // a2: initial map
573 __ lbu(t5, FieldMemOperand(a2, Map::kInstanceTypeOffset));
574 __ Branch(&rt_call, eq, t5, Operand(JS_FUNCTION_TYPE));
575
576 // Now allocate the JSObject on the heap.
577 // a1: constructor function
578 // a2: initial map
579 // a3: new target
580 __ lbu(t3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
581
582 __ Allocate(t3, t4, t3, t6, &rt_call, SIZE_IN_WORDS);
583
584 // Allocated the JSObject, now initialize the fields. Map is set to
585 // initial map and properties and elements are set to empty fixed array.
586 // a1: constructor function
587 // a2: initial map
588 // a3: new target
589 // t4: JSObject (not HeapObject tagged - the actual address).
590 // t3: start of next object
591 __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex);
592 __ mov(t5, t4);
593 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset);
594 __ sw(a2, MemOperand(t5, JSObject::kMapOffset));
595 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset);
596 __ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset));
597 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset);
598 __ sw(t6, MemOperand(t5, JSObject::kElementsOffset));
599 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize);
600 __ Addu(t5, t5, Operand(3 * kPointerSize));
601
602 // Add the object tag to make the JSObject real, so that we can continue
603 // and jump into the continuation code at any time from now on.
604 __ Addu(t4, t4, Operand(kHeapObjectTag));
605
606 // Fill all the in-object properties with appropriate filler.
607 // t4: JSObject (tagged)
608 // t5: First in-object property of JSObject (not tagged)
609 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
610
611 if (!is_api_function) {
612 Label no_inobject_slack_tracking;
613
614 MemOperand bit_field3 = FieldMemOperand(a2, Map::kBitField3Offset);
615 // Check if slack tracking is enabled.
616 __ lw(t0, bit_field3);
617 __ DecodeField<Map::ConstructionCounter>(t2, t0);
618 // t2: slack tracking counter
619 __ Branch(&no_inobject_slack_tracking, lt, t2,
620 Operand(Map::kSlackTrackingCounterEnd));
621 // Decrease generous allocation count.
622 __ Subu(t0, t0, Operand(1 << Map::ConstructionCounter::kShift));
623 __ sw(t0, bit_field3);
624
625 // Allocate object with a slack.
626 __ lbu(a0, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
627 __ sll(a0, a0, kPointerSizeLog2);
628 __ subu(a0, t3, a0);
629 // a0: offset of first field after pre-allocated fields
630 if (FLAG_debug_code) {
631 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, t5,
632 Operand(a0));
633 }
634 __ InitializeFieldsWithFiller(t5, a0, t7);
635
636 // To allow truncation fill the remaining fields with one pointer
637 // filler map.
638 __ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex);
639 __ InitializeFieldsWithFiller(t5, t3, t7);
640
641 // t2: slack tracking counter value before decreasing.
642 __ Branch(&allocated, ne, t2, Operand(Map::kSlackTrackingCounterEnd));
643
644 // Push the constructor, new_target and the object to the stack,
645 // and then the initial map as an argument to the runtime call.
646 __ Push(a1, a3, t4, a2);
647 __ CallRuntime(Runtime::kFinalizeInstanceSize);
648 __ Pop(a1, a3, t4);
649
650 // Continue with JSObject being successfully allocated.
651 // a1: constructor function
652 // a3: new target
653 // t4: JSObject
654 __ jmp(&allocated);
655
656 __ bind(&no_inobject_slack_tracking);
657 }
658
659 __ InitializeFieldsWithFiller(t5, t3, t7);
660
661 // Continue with JSObject being successfully allocated.
662 // a1: constructor function
663 // a3: new target
664 // t4: JSObject
665 __ jmp(&allocated);
666 }
667
668 // Allocate the new receiver object using the runtime call.
669 // a1: constructor function
670 // a3: new target
671 __ bind(&rt_call);
672
673 // Push the constructor and new_target twice, second pair as arguments
674 // to the runtime call.
675 __ Push(a1, a3, a1, a3); // constructor function, new target
676 __ CallRuntime(Runtime::kNewObject);
677 __ mov(t4, v0); 553 __ mov(t4, v0);
678 __ Pop(a1, a3); 554 __ Pop(a1, a3);
679 555
680 // Receiver for constructor call allocated. 556 // ----------- S t a t e -------------
681 // a1: constructor function 557 // -- a1: constructor function
682 // a3: new target 558 // -- a3: new target
683 // t4: JSObject 559 // -- t0: newly allocated object
684 __ bind(&allocated); 560 // -----------------------------------
685 561
686 // Retrieve smi-tagged arguments count from the stack. 562 // Retrieve smi-tagged arguments count from the stack.
687 __ lw(a0, MemOperand(sp)); 563 __ lw(a0, MemOperand(sp));
688 } 564 }
689 565
690 __ SmiUntag(a0); 566 __ SmiUntag(a0);
691 567
692 if (create_implicit_receiver) { 568 if (create_implicit_receiver) {
693 // Push the allocated receiver to the stack. We need two copies 569 // Push the allocated receiver to the stack. We need two copies
694 // because we may have to return the original one and the calling 570 // because we may have to return the original one and the calling
(...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after
2765 } 2641 }
2766 } 2642 }
2767 2643
2768 2644
2769 #undef __ 2645 #undef __
2770 2646
2771 } // namespace internal 2647 } // namespace internal
2772 } // namespace v8 2648 } // namespace v8
2773 2649
2774 #endif // V8_TARGET_ARCH_MIPS 2650 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698