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

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

Issue 132963012: Pretenure call new support. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment response. Created 6 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 | Annotate | Revision Log
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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); 332 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
333 GenerateTailCallToReturnedCode(masm); 333 GenerateTailCallToReturnedCode(masm);
334 334
335 __ bind(&ok); 335 __ bind(&ok);
336 GenerateTailCallToSharedCode(masm); 336 GenerateTailCallToSharedCode(masm);
337 } 337 }
338 338
339 339
340 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 340 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
341 bool is_api_function, 341 bool is_api_function,
342 bool count_constructions) { 342 bool count_constructions,
343 bool create_memento) {
343 // ----------- S t a t e ------------- 344 // ----------- S t a t e -------------
344 // -- r0 : number of arguments 345 // -- r0 : number of arguments
345 // -- r1 : constructor function 346 // -- r1 : constructor function
347 // -- r2 : allocation site or undefined
346 // -- lr : return address 348 // -- lr : return address
347 // -- sp[...]: constructor arguments 349 // -- sp[...]: constructor arguments
348 // ----------------------------------- 350 // -----------------------------------
349 351
350 // Should never count constructions for api objects. 352 // Should never count constructions for api objects.
351 ASSERT(!is_api_function || !count_constructions); 353 ASSERT(!is_api_function || !count_constructions);
352 354
355 // Should never create mementos for api functions.
356 ASSERT(!is_api_function || !create_memento);
357
358 // Should never create mementos before slack tracking is finished.
359 ASSERT(!count_constructions || !create_memento);
360
353 Isolate* isolate = masm->isolate(); 361 Isolate* isolate = masm->isolate();
354 362
355 // Enter a construct frame. 363 // Enter a construct frame.
356 { 364 {
357 FrameScope scope(masm, StackFrame::CONSTRUCT); 365 FrameScope scope(masm, StackFrame::CONSTRUCT);
358 366
367 if (create_memento) {
368 __ AssertUndefinedOrAllocationSite(r2, r3);
369 __ push(r2);
370 }
371
359 // Preserve the two incoming parameters on the stack. 372 // Preserve the two incoming parameters on the stack.
360 __ SmiTag(r0); 373 __ SmiTag(r0);
361 __ push(r0); // Smi-tagged arguments count. 374 __ push(r0); // Smi-tagged arguments count.
362 __ push(r1); // Constructor function. 375 __ push(r1); // Constructor function.
363 376
364 // Try to allocate the object without transitioning into C code. If any of 377 // Try to allocate the object without transitioning into C code. If any of
365 // the preconditions is not met, the code bails out to the runtime call. 378 // the preconditions is not met, the code bails out to the runtime call.
366 Label rt_call, allocated; 379 Label rt_call, allocated;
367 if (FLAG_inline_new) { 380 if (FLAG_inline_new) {
368 Label undo_allocation; 381 Label undo_allocation;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 __ pop(r2); 423 __ pop(r2);
411 __ pop(r1); 424 __ pop(r1);
412 425
413 __ bind(&allocate); 426 __ bind(&allocate);
414 } 427 }
415 428
416 // Now allocate the JSObject on the heap. 429 // Now allocate the JSObject on the heap.
417 // r1: constructor function 430 // r1: constructor function
418 // r2: initial map 431 // r2: initial map
419 __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset)); 432 __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
433 if (create_memento) {
434 __ add(r3, r3, Operand(AllocationMemento::kSize / kPointerSize));
435 }
436
420 __ Allocate(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS); 437 __ Allocate(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS);
421 438
422 // Allocated the JSObject, now initialize the fields. Map is set to 439 // Allocated the JSObject, now initialize the fields. Map is set to
423 // initial map and properties and elements are set to empty fixed array. 440 // initial map and properties and elements are set to empty fixed array.
424 // r1: constructor function 441 // r1: constructor function
425 // r2: initial map 442 // r2: initial map
426 // r3: object size 443 // r3: object size (not including memento if create_memento)
427 // r4: JSObject (not tagged) 444 // r4: JSObject (not tagged)
428 __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex); 445 __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
429 __ mov(r5, r4); 446 __ mov(r5, r4);
430 ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset); 447 ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
431 __ str(r2, MemOperand(r5, kPointerSize, PostIndex)); 448 __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
432 ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset); 449 ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
433 __ str(r6, MemOperand(r5, kPointerSize, PostIndex)); 450 __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
434 ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset); 451 ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
435 __ str(r6, MemOperand(r5, kPointerSize, PostIndex)); 452 __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
436 453
437 // Fill all the in-object properties with the appropriate filler. 454 // Fill all the in-object properties with the appropriate filler.
438 // r1: constructor function 455 // r1: constructor function
439 // r2: initial map 456 // r2: initial map
440 // r3: object size (in words) 457 // r3: object size (in words, including memento if create_memento)
441 // r4: JSObject (not tagged) 458 // r4: JSObject (not tagged)
442 // r5: First in-object property of JSObject (not tagged) 459 // r5: First in-object property of JSObject (not tagged)
443 ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize); 460 ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);
444 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); 461
445 if (count_constructions) { 462 if (count_constructions) {
463 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
446 __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); 464 __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset));
447 __ Ubfx(r0, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, 465 __ Ubfx(r0, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
448 kBitsPerByte); 466 kBitsPerByte);
449 __ add(r0, r5, Operand(r0, LSL, kPointerSizeLog2)); 467 __ add(r0, r5, Operand(r0, LSL, kPointerSizeLog2));
450 // r0: offset of first field after pre-allocated fields 468 // r0: offset of first field after pre-allocated fields
451 if (FLAG_debug_code) { 469 if (FLAG_debug_code) {
452 __ add(ip, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object. 470 __ add(ip, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object.
453 __ cmp(r0, ip); 471 __ cmp(r0, ip);
454 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); 472 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
455 } 473 }
456 __ InitializeFieldsWithFiller(r5, r0, r6); 474 __ InitializeFieldsWithFiller(r5, r0, r6);
457 // To allow for truncation. 475 // To allow for truncation.
458 __ LoadRoot(r6, Heap::kOnePointerFillerMapRootIndex); 476 __ LoadRoot(r6, Heap::kOnePointerFillerMapRootIndex);
477 __ add(r0, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object.
478 __ InitializeFieldsWithFiller(r5, r0, r6);
479 } else if (create_memento) {
480 __ sub(r6, r3, Operand(AllocationMemento::kSize / kPointerSize));
481 __ add(r0, r4, Operand(r6, LSL, kPointerSizeLog2)); // End of object.
482 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
483 __ InitializeFieldsWithFiller(r5, r0, r6);
484
485 // Fill in memento fields.
486 // r5: points to the allocated but uninitialized memento.
487 __ LoadRoot(r6, Heap::kAllocationMementoMapRootIndex);
488 ASSERT_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
489 __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
490 // Load the AllocationSite
491 __ ldr(r6, MemOperand(sp, 2 * kPointerSize));
492 ASSERT_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
493 __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
494 } else {
495 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
496 __ add(r0, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object.
497 __ InitializeFieldsWithFiller(r5, r0, r6);
459 } 498 }
Hannes Payer (out of office) 2014/02/18 16:24:26 Is it possible to keep __ add(r0, r4, Operand(r3,
460 __ add(r0, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object.
461 __ InitializeFieldsWithFiller(r5, r0, r6);
462 499
463 // Add the object tag to make the JSObject real, so that we can continue 500 // Add the object tag to make the JSObject real, so that we can continue
464 // and jump into the continuation code at any time from now on. Any 501 // and jump into the continuation code at any time from now on. Any
465 // failures need to undo the allocation, so that the heap is in a 502 // failures need to undo the allocation, so that the heap is in a
466 // consistent state and verifiable. 503 // consistent state and verifiable.
467 __ add(r4, r4, Operand(kHeapObjectTag)); 504 __ add(r4, r4, Operand(kHeapObjectTag));
468 505
469 // Check if a non-empty properties array is needed. Continue with 506 // Check if a non-empty properties array is needed. Continue with
470 // allocated object if not fall through to runtime call if it is. 507 // allocated object if not fall through to runtime call if it is.
471 // r1: constructor function 508 // r1: constructor function
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 // example, the map's unused properties potentially do not match the 586 // example, the map's unused properties potentially do not match the
550 // allocated objects unused properties. 587 // allocated objects unused properties.
551 // r4: JSObject (previous new top) 588 // r4: JSObject (previous new top)
552 __ bind(&undo_allocation); 589 __ bind(&undo_allocation);
553 __ UndoAllocationInNewSpace(r4, r5); 590 __ UndoAllocationInNewSpace(r4, r5);
554 } 591 }
555 592
556 // Allocate the new receiver object using the runtime call. 593 // Allocate the new receiver object using the runtime call.
557 // r1: constructor function 594 // r1: constructor function
558 __ bind(&rt_call); 595 __ bind(&rt_call);
596 if (create_memento) {
597 // Get the cell or allocation site.
598 __ ldr(r2, MemOperand(sp, 2 * kPointerSize));
599 __ push(r2);
600 }
601
559 __ push(r1); // argument for Runtime_NewObject 602 __ push(r1); // argument for Runtime_NewObject
560 __ CallRuntime(Runtime::kNewObject, 1); 603 if (create_memento) {
604 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2);
605 } else {
606 __ CallRuntime(Runtime::kNewObject, 1);
607 }
561 __ mov(r4, r0); 608 __ mov(r4, r0);
562 609
610 // If we ended up using the runtime, and we want a memento, then the
611 // runtime call made it for us, and we shouldn't do create count
612 // increment.
613 Label count_incremented;
614 if (create_memento) {
615 __ jmp(&count_incremented);
616 }
617
563 // Receiver for constructor call allocated. 618 // Receiver for constructor call allocated.
564 // r4: JSObject 619 // r4: JSObject
565 __ bind(&allocated); 620 __ bind(&allocated);
621
622 if (create_memento) {
623 __ ldr(r2, MemOperand(sp, kPointerSize * 2));
624 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
625 __ cmp(r2, r5);
626 __ b(eq, &count_incremented);
627 // r2 is an AllocationSite. We are creating a memento from it, so we
628 // need to increment the memento create count.
629 __ ldr(r3, FieldMemOperand(r2,
630 AllocationSite::kPretenureCreateCountOffset));
631 __ add(r3, r3, Operand(Smi::FromInt(1)));
632 __ str(r3, FieldMemOperand(r2,
633 AllocationSite::kPretenureCreateCountOffset));
634 __ bind(&count_incremented);
635 }
Hannes Payer (out of office) 2014/02/18 16:24:26 bind outside if?
636
566 __ push(r4); 637 __ push(r4);
567 __ push(r4); 638 __ push(r4);
568 639
569 // Reload the number of arguments and the constructor from the stack. 640 // Reload the number of arguments and the constructor from the stack.
570 // sp[0]: receiver 641 // sp[0]: receiver
571 // sp[1]: receiver 642 // sp[1]: receiver
572 // sp[2]: constructor function 643 // sp[2]: constructor function
573 // sp[3]: number of arguments (smi-tagged) 644 // sp[3]: number of arguments (smi-tagged)
574 __ ldr(r1, MemOperand(sp, 2 * kPointerSize)); 645 __ ldr(r1, MemOperand(sp, 2 * kPointerSize));
575 __ ldr(r3, MemOperand(sp, 3 * kPointerSize)); 646 __ ldr(r3, MemOperand(sp, 3 * kPointerSize));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 } 729 }
659 730
660 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); 731 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
661 __ add(sp, sp, Operand(kPointerSize)); 732 __ add(sp, sp, Operand(kPointerSize));
662 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2); 733 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2);
663 __ Jump(lr); 734 __ Jump(lr);
664 } 735 }
665 736
666 737
667 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { 738 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
668 Generate_JSConstructStubHelper(masm, false, true); 739 Generate_JSConstructStubHelper(masm, false, true, false);
669 } 740 }
670 741
671 742
672 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 743 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
673 Generate_JSConstructStubHelper(masm, false, false); 744 Generate_JSConstructStubHelper(masm, false, false, true);
674 } 745 }
675 746
676 747
677 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 748 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
678 Generate_JSConstructStubHelper(masm, true, false); 749 Generate_JSConstructStubHelper(masm, true, false, false);
679 } 750 }
680 751
681 752
682 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 753 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
683 bool is_construct) { 754 bool is_construct) {
684 // Called from Generate_JS_Entry 755 // Called from Generate_JS_Entry
685 // r0: code entry 756 // r0: code entry
686 // r1: function 757 // r1: function
687 // r2: receiver 758 // r2: receiver
688 // r3: argc 759 // r3: argc
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 __ bind(&dont_adapt_arguments); 1539 __ bind(&dont_adapt_arguments);
1469 __ Jump(r3); 1540 __ Jump(r3);
1470 } 1541 }
1471 1542
1472 1543
1473 #undef __ 1544 #undef __
1474 1545
1475 } } // namespace v8::internal 1546 } } // namespace v8::internal
1476 1547
1477 #endif // V8_TARGET_ARCH_ARM 1548 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698