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

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

Powered by Google App Engine
This is Rietveld 408576698