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

Side by Side Diff: src/a64/builtins-a64.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 | « no previous file | src/a64/code-stubs-a64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); 320 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
321 GenerateTailCallToReturnedCode(masm); 321 GenerateTailCallToReturnedCode(masm);
322 322
323 __ Bind(&ok); 323 __ Bind(&ok);
324 GenerateTailCallToSharedCode(masm); 324 GenerateTailCallToSharedCode(masm);
325 } 325 }
326 326
327 327
328 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 328 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
329 bool is_api_function, 329 bool is_api_function,
330 bool count_constructions) { 330 bool count_constructions,
331 bool create_memento) {
331 // ----------- S t a t e ------------- 332 // ----------- S t a t e -------------
332 // -- x0 : number of arguments 333 // -- x0 : number of arguments
333 // -- x1 : constructor function 334 // -- x1 : constructor function
335 // -- x2 : allocation site or undefined
334 // -- lr : return address 336 // -- lr : return address
335 // -- sp[...]: constructor arguments 337 // -- sp[...]: constructor arguments
336 // ----------------------------------- 338 // -----------------------------------
337 339
338 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); 340 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper");
339 // Should never count constructions for api objects. 341 // Should never count constructions for api objects.
340 ASSERT(!is_api_function || !count_constructions); 342 ASSERT(!is_api_function || !count_constructions);
343 // Should never create mementos for api functions.
344 ASSERT(!is_api_function || !create_memento);
345 // Should never create mementos before slack tracking is finished.
346 ASSERT(!count_constructions || !create_memento);
341 347
342 Isolate* isolate = masm->isolate(); 348 Isolate* isolate = masm->isolate();
343 349
344 // Enter a construct frame. 350 // Enter a construct frame.
345 { 351 {
346 FrameScope scope(masm, StackFrame::CONSTRUCT); 352 FrameScope scope(masm, StackFrame::CONSTRUCT);
347 353
348 // Preserve the two incoming parameters on the stack. 354 // Preserve the three incoming parameters on the stack.
355 if (create_memento) {
356 __ AssertUndefinedOrAllocationSite(x2, x10);
357 __ Push(x2);
358 }
359
349 Register argc = x0; 360 Register argc = x0;
350 Register constructor = x1; 361 Register constructor = x1;
351 // x1: constructor function 362 // x1: constructor function
352 __ SmiTag(argc); 363 __ SmiTag(argc);
353 __ Push(argc, constructor); 364 __ Push(argc, constructor);
354 // sp[0] : Constructor function. 365 // sp[0] : Constructor function.
355 // sp[1]: number of arguments (smi-tagged) 366 // sp[1]: number of arguments (smi-tagged)
356 367
357 // Try to allocate the object without transitioning into C code. If any of 368 // Try to allocate the object without transitioning into C code. If any of
358 // the preconditions is not met, the code bails out to the runtime call. 369 // 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
398 // The call will replace the stub, so the countdown is only done once. 409 // The call will replace the stub, so the countdown is only done once.
399 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); 410 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
400 __ Pop(init_map, constructor); 411 __ Pop(init_map, constructor);
401 __ Bind(&allocate); 412 __ Bind(&allocate);
402 } 413 }
403 414
404 // Now allocate the JSObject on the heap. 415 // Now allocate the JSObject on the heap.
405 Register obj_size = x3; 416 Register obj_size = x3;
406 Register new_obj = x4; 417 Register new_obj = x4;
407 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); 418 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset));
408 __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); 419 if (create_memento) {
420 __ Add(x7, obj_size,
421 Operand(AllocationMemento::kSize / kPointerSize));
422 __ Allocate(x7, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS);
423 } else {
424 __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS);
425 }
409 426
410 // Allocated the JSObject, now initialize the fields. Map is set to 427 // Allocated the JSObject, now initialize the fields. Map is set to
411 // initial map and properties and elements are set to empty fixed array. 428 // initial map and properties and elements are set to empty fixed array.
412 // NB. the object pointer is not tagged, so MemOperand is used. 429 // NB. the object pointer is not tagged, so MemOperand is used.
413 Register empty = x5; 430 Register empty = x5;
414 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); 431 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
415 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); 432 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset));
416 STATIC_ASSERT(JSObject::kElementsOffset == 433 STATIC_ASSERT(JSObject::kElementsOffset ==
417 (JSObject::kPropertiesOffset + kPointerSize)); 434 (JSObject::kPropertiesOffset + kPointerSize));
418 __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); 435 __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 } 477 }
461 478
462 // Fill the remaining fields with one pointer filler map. 479 // Fill the remaining fields with one pointer filler map.
463 Register one_pointer_filler = x5; 480 Register one_pointer_filler = x5;
464 Register non_prealloc_fields = x6; 481 Register non_prealloc_fields = x6;
465 __ LoadRoot(one_pointer_filler, Heap::kOnePointerFillerMapRootIndex); 482 __ LoadRoot(one_pointer_filler, Heap::kOnePointerFillerMapRootIndex);
466 __ Sub(non_prealloc_fields, prop_fields, prealloc_fields); 483 __ Sub(non_prealloc_fields, prop_fields, prealloc_fields);
467 __ FillFields(first_non_prealloc, non_prealloc_fields, 484 __ FillFields(first_non_prealloc, non_prealloc_fields,
468 one_pointer_filler); 485 one_pointer_filler);
469 prop_fields = NoReg; 486 prop_fields = NoReg;
487 } else if (create_memento) {
488 // Fill the pre-allocated fields with undef.
489 __ FillFields(first_prop, prop_fields, undef);
490 __ Add(first_prop, new_obj, Operand(obj_size, LSL, kPointerSizeLog2));
491 __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex);
492 ASSERT_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
493 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
494 // Load the AllocationSite
495 __ Peek(x14, 2 * kXRegSize);
496 ASSERT_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
497 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
498 first_prop = NoReg;
470 } else { 499 } else {
471 // Fill all of the property fields with undef. 500 // Fill all of the property fields with undef.
472 __ FillFields(first_prop, prop_fields, undef); 501 __ FillFields(first_prop, prop_fields, undef);
473 first_prop = NoReg; 502 first_prop = NoReg;
474 prop_fields = NoReg; 503 prop_fields = NoReg;
475 } 504 }
476 505
477 // Add the object tag to make the JSObject real, so that we can continue 506 // Add the object tag to make the JSObject real, so that we can continue
478 // and jump into the continuation code at any time from now on. Any 507 // and jump into the continuation code at any time from now on. Any
479 // failures need to undo the allocation, so that the heap is in a 508 // failures need to undo the allocation, so that the heap is in a
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 553
525 // Undo the setting of the new top so that the heap is verifiable. For 554 // Undo the setting of the new top so that the heap is verifiable. For
526 // example, the map's unused properties potentially do not match the 555 // example, the map's unused properties potentially do not match the
527 // allocated objects unused properties. 556 // allocated objects unused properties.
528 __ Bind(&undo_allocation); 557 __ Bind(&undo_allocation);
529 __ UndoAllocationInNewSpace(new_obj, x14); 558 __ UndoAllocationInNewSpace(new_obj, x14);
530 } 559 }
531 560
532 // Allocate the new receiver object using the runtime call. 561 // Allocate the new receiver object using the runtime call.
533 __ Bind(&rt_call); 562 __ Bind(&rt_call);
534 __ Push(constructor); // Argument for Runtime_NewObject. 563 Label count_incremented;
535 __ CallRuntime(Runtime::kNewObject, 1); 564 if (create_memento) {
536 __ Mov(x4, x0); 565 // Get the cell or allocation site.
566 __ Peek(x4, 2 * kXRegSize);
567 __ Push(x4);
568 __ Push(constructor); // Argument for Runtime_NewObject.
569 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2);
570 __ Mov(x4, x0);
571 // If we ended up using the runtime, and we want a memento, then the
572 // runtime call made it for us, and we shouldn't do create count
573 // increment.
574 __ jmp(&count_incremented);
575 } else {
576 __ Push(constructor); // Argument for Runtime_NewObject.
577 __ CallRuntime(Runtime::kNewObject, 1);
578 __ Mov(x4, x0);
579 }
537 580
538 // Receiver for constructor call allocated. 581 // Receiver for constructor call allocated.
539 // x4: JSObject 582 // x4: JSObject
540 __ Bind(&allocated); 583 __ Bind(&allocated);
584
585 if (create_memento) {
586 __ Peek(x10, 2 * kXRegSize);
587 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented);
588 // r2 is an AllocationSite. We are creating a memento from it, so we
589 // need to increment the memento create count.
590 __ Ldr(x5, FieldMemOperand(x10,
591 AllocationSite::kPretenureCreateCountOffset));
592 __ Add(x5, x5, Operand(Smi::FromInt(1)));
593 __ Str(x5, FieldMemOperand(x10,
594 AllocationSite::kPretenureCreateCountOffset));
595 __ bind(&count_incremented);
596 }
597
541 __ Push(x4, x4); 598 __ Push(x4, x4);
542 599
543 // Reload the number of arguments from the stack. 600 // Reload the number of arguments from the stack.
544 // Set it up in x0 for the function call below. 601 // Set it up in x0 for the function call below.
545 // jssp[0]: receiver 602 // jssp[0]: receiver
546 // jssp[1]: receiver 603 // jssp[1]: receiver
547 // jssp[2]: constructor function 604 // jssp[2]: constructor function
548 // jssp[3]: number of arguments (smi-tagged) 605 // jssp[3]: number of arguments (smi-tagged)
549 __ Peek(constructor, 2 * kXRegSize); // Load constructor. 606 __ Peek(constructor, 2 * kXRegSize); // Load constructor.
550 __ Peek(argc, 3 * kXRegSize); // Load number of arguments. 607 __ Peek(argc, 3 * kXRegSize); // Load number of arguments.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 } 694 }
638 695
639 __ DropBySMI(x1); 696 __ DropBySMI(x1);
640 __ Drop(1); 697 __ Drop(1);
641 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); 698 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2);
642 __ Ret(); 699 __ Ret();
643 } 700 }
644 701
645 702
646 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { 703 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
647 Generate_JSConstructStubHelper(masm, false, true); 704 Generate_JSConstructStubHelper(masm, false, true, false);
648 } 705 }
649 706
650 707
651 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 708 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
652 Generate_JSConstructStubHelper(masm, false, false); 709 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
653 } 710 }
654 711
655 712
656 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 713 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
657 Generate_JSConstructStubHelper(masm, true, false); 714 Generate_JSConstructStubHelper(masm, true, false, false);
658 } 715 }
659 716
660 717
661 // Input: 718 // Input:
662 // x0: code entry. 719 // x0: code entry.
663 // x1: function. 720 // x1: function.
664 // x2: receiver. 721 // x2: receiver.
665 // x3: argc. 722 // x3: argc.
666 // x4: argv. 723 // x4: argv.
667 // Output: 724 // Output:
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 __ Bind(&dont_adapt_arguments); 1553 __ Bind(&dont_adapt_arguments);
1497 __ Jump(code_entry); 1554 __ Jump(code_entry);
1498 } 1555 }
1499 1556
1500 1557
1501 #undef __ 1558 #undef __
1502 1559
1503 } } // namespace v8::internal 1560 } } // namespace v8::internal
1504 1561
1505 #endif // V8_TARGET_ARCH_ARM 1562 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/a64/code-stubs-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698