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

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

Issue 203463013: MIPS: Pretenure call new support. (Closed) Base URL: https://github.com/v8/v8.git@gbl
Patch Set: Created 6 years, 9 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
« no previous file with comments | « no previous file | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); 335 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
336 GenerateTailCallToReturnedCode(masm); 336 GenerateTailCallToReturnedCode(masm);
337 337
338 __ bind(&ok); 338 __ bind(&ok);
339 GenerateTailCallToSharedCode(masm); 339 GenerateTailCallToSharedCode(masm);
340 } 340 }
341 341
342 342
343 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 343 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
344 bool is_api_function, 344 bool is_api_function,
345 bool count_constructions) { 345 bool count_constructions,
346 bool create_memento) {
346 // ----------- S t a t e ------------- 347 // ----------- S t a t e -------------
347 // -- a0 : number of arguments 348 // -- a0 : number of arguments
348 // -- a1 : constructor function 349 // -- a1 : constructor function
350 // -- a2 : allocation site or undefined
349 // -- ra : return address 351 // -- ra : return address
350 // -- sp[...]: constructor arguments 352 // -- sp[...]: constructor arguments
351 // ----------------------------------- 353 // -----------------------------------
352 354
353 // Should never count constructions for api objects. 355 // Should never count constructions for api objects.
354 ASSERT(!is_api_function || !count_constructions); 356 ASSERT(!is_api_function || !count_constructions);
355 357
358 // Should never create mementos for api functions.
359 ASSERT(!is_api_function || !create_memento);
360
361 // Should never create mementos before slack tracking is finished.
362 ASSERT(!count_constructions || !create_memento);
363
356 Isolate* isolate = masm->isolate(); 364 Isolate* isolate = masm->isolate();
357 365
358 // ----------- S t a t e ------------- 366 // ----------- S t a t e -------------
359 // -- a0 : number of arguments 367 // -- a0 : number of arguments
360 // -- a1 : constructor function 368 // -- a1 : constructor function
361 // -- ra : return address 369 // -- ra : return address
362 // -- sp[...]: constructor arguments 370 // -- sp[...]: constructor arguments
363 // ----------------------------------- 371 // -----------------------------------
364 372
365 // Enter a construct frame. 373 // Enter a construct frame.
366 { 374 {
367 FrameScope scope(masm, StackFrame::CONSTRUCT); 375 FrameScope scope(masm, StackFrame::CONSTRUCT);
368 376
377 if (create_memento) {
378 __ AssertUndefinedOrAllocationSite(a2, a3);
379 __ push(a2);
380 }
381
369 // Preserve the two incoming parameters on the stack. 382 // Preserve the two incoming parameters on the stack.
370 __ sll(a0, a0, kSmiTagSize); // Tag arguments count. 383 __ sll(a0, a0, kSmiTagSize); // Tag arguments count.
371 __ MultiPushReversed(a0.bit() | a1.bit()); 384 __ MultiPushReversed(a0.bit() | a1.bit());
372 385
373 // Use t7 to hold undefined, which is used in several places below. 386 // Use t7 to hold undefined, which is used in several places below.
374 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex); 387 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
375 388
376 Label rt_call, allocated; 389 Label rt_call, allocated;
377 // Try to allocate the object without transitioning into C code. If any of 390 // Try to allocate the object without transitioning into C code. If any of
378 // the preconditions is not met, the code bails out to the runtime call. 391 // the preconditions is not met, the code bails out to the runtime call.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 431
419 __ Pop(a1, a2); 432 __ Pop(a1, a2);
420 433
421 __ bind(&allocate); 434 __ bind(&allocate);
422 } 435 }
423 436
424 // Now allocate the JSObject on the heap. 437 // Now allocate the JSObject on the heap.
425 // a1: constructor function 438 // a1: constructor function
426 // a2: initial map 439 // a2: initial map
427 __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset)); 440 __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
441 if (create_memento) {
442 __ Addu(a3, a3, Operand(AllocationMemento::kSize / kPointerSize));
443 }
444
428 __ Allocate(a3, t4, t5, t6, &rt_call, SIZE_IN_WORDS); 445 __ Allocate(a3, t4, t5, t6, &rt_call, SIZE_IN_WORDS);
429 446
430 // Allocated the JSObject, now initialize the fields. Map is set to 447 // Allocated the JSObject, now initialize the fields. Map is set to
431 // initial map and properties and elements are set to empty fixed array. 448 // initial map and properties and elements are set to empty fixed array.
432 // a1: constructor function 449 // a1: constructor function
433 // a2: initial map 450 // a2: initial map
434 // a3: object size 451 // a3: object size (not including memento if create_memento)
435 // t4: JSObject (not tagged) 452 // t4: JSObject (not tagged)
436 __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex); 453 __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex);
437 __ mov(t5, t4); 454 __ mov(t5, t4);
438 __ sw(a2, MemOperand(t5, JSObject::kMapOffset)); 455 __ sw(a2, MemOperand(t5, JSObject::kMapOffset));
439 __ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset)); 456 __ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset));
440 __ sw(t6, MemOperand(t5, JSObject::kElementsOffset)); 457 __ sw(t6, MemOperand(t5, JSObject::kElementsOffset));
441 __ Addu(t5, t5, Operand(3*kPointerSize)); 458 __ Addu(t5, t5, Operand(3*kPointerSize));
442 ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset); 459 ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
443 ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset); 460 ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
444 ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset); 461 ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
445 462
446 // Fill all the in-object properties with appropriate filler. 463 // Fill all the in-object properties with appropriate filler.
447 // a1: constructor function 464 // a1: constructor function
448 // a2: initial map 465 // a2: initial map
449 // a3: object size (in words) 466 // a3: object size (in words, including memento if create_memento)
450 // t4: JSObject (not tagged) 467 // t4: JSObject (not tagged)
451 // t5: First in-object property of JSObject (not tagged) 468 // t5: First in-object property of JSObject (not tagged)
452 __ sll(t0, a3, kPointerSizeLog2);
453 __ addu(t6, t4, t0); // End of object.
454 ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize); 469 ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);
455 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex); 470
456 if (count_constructions) { 471 if (count_constructions) {
472 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
457 __ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset)); 473 __ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
458 __ Ext(a0, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, 474 __ Ext(a0, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
459 kBitsPerByte); 475 kBitsPerByte);
460 __ sll(t0, a0, kPointerSizeLog2); 476 __ sll(t0, a0, kPointerSizeLog2);
461 __ addu(a0, t5, t0); 477 __ addu(a0, t5, t0);
462 // a0: offset of first field after pre-allocated fields 478 // a0: offset of first field after pre-allocated fields
463 if (FLAG_debug_code) { 479 if (FLAG_debug_code) {
464 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, 480 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields,
465 a0, Operand(t6)); 481 a0, Operand(t6));
466 } 482 }
467 __ InitializeFieldsWithFiller(t5, a0, t7); 483 __ InitializeFieldsWithFiller(t5, a0, t7);
468 // To allow for truncation. 484 // To allow for truncation.
469 __ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex); 485 __ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex);
486 __ sll(at, a3, kPointerSizeLog2);
487 __ Addu(a0, t4, Operand(at)); // End of object.
488 __ InitializeFieldsWithFiller(t5, a0, t7);
489 } else if (create_memento) {
490 __ Subu(t7, a3, Operand(AllocationMemento::kSize / kPointerSize));
491 __ sll(at, t7, kPointerSizeLog2);
492 __ Addu(a0, t4, Operand(at)); // End of object.
493 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
494 __ InitializeFieldsWithFiller(t5, a0, t7);
495
496 // Fill in memento fields.
497 // t5: points to the allocated but uninitialized memento.
498 __ LoadRoot(t7, Heap::kAllocationMementoMapRootIndex);
499 ASSERT_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
500 __ sw(t7, MemOperand(t5));
501 __ Addu(t5, t5, kPointerSize);
502 // Load the AllocationSite.
503 __ lw(t7, MemOperand(sp, 2 * kPointerSize));
504 ASSERT_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
505 __ sw(t7, MemOperand(t5));
506 __ Addu(t5, t5, kPointerSize);
507 } else {
508 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
509 __ sll(at, a3, kPointerSizeLog2);
510 __ Addu(a0, t4, Operand(at)); // End of object.
511 __ InitializeFieldsWithFiller(t5, a0, t7);
470 } 512 }
471 __ InitializeFieldsWithFiller(t5, t6, t7);
472 513
473 // Add the object tag to make the JSObject real, so that we can continue 514 // Add the object tag to make the JSObject real, so that we can continue
474 // and jump into the continuation code at any time from now on. Any 515 // and jump into the continuation code at any time from now on. Any
475 // failures need to undo the allocation, so that the heap is in a 516 // failures need to undo the allocation, so that the heap is in a
476 // consistent state and verifiable. 517 // consistent state and verifiable.
477 __ Addu(t4, t4, Operand(kHeapObjectTag)); 518 __ Addu(t4, t4, Operand(kHeapObjectTag));
478 519
479 // Check if a non-empty properties array is needed. Continue with 520 // Check if a non-empty properties array is needed. Continue with
480 // allocated object if not fall through to runtime call if it is. 521 // allocated object if not fall through to runtime call if it is.
481 // a1: constructor function 522 // a1: constructor function
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 __ jmp(&allocated); 606 __ jmp(&allocated);
566 607
567 // Undo the setting of the new top so that the heap is verifiable. For 608 // Undo the setting of the new top so that the heap is verifiable. For
568 // example, the map's unused properties potentially do not match the 609 // example, the map's unused properties potentially do not match the
569 // allocated objects unused properties. 610 // allocated objects unused properties.
570 // t4: JSObject (previous new top) 611 // t4: JSObject (previous new top)
571 __ bind(&undo_allocation); 612 __ bind(&undo_allocation);
572 __ UndoAllocationInNewSpace(t4, t5); 613 __ UndoAllocationInNewSpace(t4, t5);
573 } 614 }
574 615
575 __ bind(&rt_call);
576 // Allocate the new receiver object using the runtime call. 616 // Allocate the new receiver object using the runtime call.
577 // a1: constructor function 617 // a1: constructor function
618 __ bind(&rt_call);
619 if (create_memento) {
620 // Get the cell or allocation site.
621 __ lw(a2, MemOperand(sp, 2 * kPointerSize));
622 __ push(a2);
623 }
624
578 __ push(a1); // Argument for Runtime_NewObject. 625 __ push(a1); // Argument for Runtime_NewObject.
579 __ CallRuntime(Runtime::kNewObject, 1); 626 if (create_memento) {
627 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2);
628 } else {
629 __ CallRuntime(Runtime::kNewObject, 1);
630 }
580 __ mov(t4, v0); 631 __ mov(t4, v0);
581 632
633 // If we ended up using the runtime, and we want a memento, then the
634 // runtime call made it for us, and we shouldn't do create count
635 // increment.
636 Label count_incremented;
637 if (create_memento) {
638 __ jmp(&count_incremented);
639 }
640
582 // Receiver for constructor call allocated. 641 // Receiver for constructor call allocated.
583 // t4: JSObject 642 // t4: JSObject
643
644 if (create_memento) {
645 __ lw(a2, MemOperand(sp, kPointerSize * 2));
646 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex);
647 __ Branch(&count_incremented, eq, a2, Operand(t5));
648 // a2 is an AllocationSite. We are creating a memento from it, so we
649 // need to increment the memento create count.
650 __ lw(a3, FieldMemOperand(a2,
651 AllocationSite::kPretenureCreateCountOffset));
652 __ Addu(a3, a3, Operand(Smi::FromInt(1)));
653 __ sw(a3, FieldMemOperand(a2,
654 AllocationSite::kPretenureCreateCountOffset));
655 __ bind(&count_incremented);
656 }
657
584 __ bind(&allocated); 658 __ bind(&allocated);
585 __ Push(t4, t4); 659 __ Push(t4, t4);
586 660
587 // Reload the number of arguments from the stack. 661 // Reload the number of arguments from the stack.
588 // sp[0]: receiver 662 // sp[0]: receiver
589 // sp[1]: receiver 663 // sp[1]: receiver
590 // sp[2]: constructor function 664 // sp[2]: constructor function
591 // sp[3]: number of arguments (smi-tagged) 665 // sp[3]: number of arguments (smi-tagged)
592 __ lw(a1, MemOperand(sp, 2 * kPointerSize)); 666 __ lw(a1, MemOperand(sp, 2 * kPointerSize));
593 __ lw(a3, MemOperand(sp, 3 * kPointerSize)); 667 __ lw(a3, MemOperand(sp, 3 * kPointerSize));
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 749
676 __ sll(t0, a1, kPointerSizeLog2 - 1); 750 __ sll(t0, a1, kPointerSizeLog2 - 1);
677 __ Addu(sp, sp, t0); 751 __ Addu(sp, sp, t0);
678 __ Addu(sp, sp, kPointerSize); 752 __ Addu(sp, sp, kPointerSize);
679 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2); 753 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2);
680 __ Ret(); 754 __ Ret();
681 } 755 }
682 756
683 757
684 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { 758 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
685 Generate_JSConstructStubHelper(masm, false, true); 759 Generate_JSConstructStubHelper(masm, false, true, false);
686 } 760 }
687 761
688 762
689 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 763 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
690 Generate_JSConstructStubHelper(masm, false, false); 764 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
691 } 765 }
692 766
693 767
694 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 768 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
695 Generate_JSConstructStubHelper(masm, true, false); 769 Generate_JSConstructStubHelper(masm, true, false, false);
696 } 770 }
697 771
698 772
699 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 773 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
700 bool is_construct) { 774 bool is_construct) {
701 // Called from JSEntryStub::GenerateBody 775 // Called from JSEntryStub::GenerateBody
702 776
703 // ----------- S t a t e ------------- 777 // ----------- S t a t e -------------
704 // -- a0: code entry 778 // -- a0: code entry
705 // -- a1: function 779 // -- a1: function
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 __ bind(&dont_adapt_arguments); 1569 __ bind(&dont_adapt_arguments);
1496 __ Jump(a3); 1570 __ Jump(a3);
1497 } 1571 }
1498 1572
1499 1573
1500 #undef __ 1574 #undef __
1501 1575
1502 } } // namespace v8::internal 1576 } } // namespace v8::internal
1503 1577
1504 #endif // V8_TARGET_ARCH_MIPS 1578 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698