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

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: 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
« no previous file with comments | « no previous file | src/a64/code-stubs-a64.cc » ('j') | src/a64/code-stubs-a64.cc » ('J')
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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); 322 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
323 GenerateTailCallToReturnedCode(masm); 323 GenerateTailCallToReturnedCode(masm);
324 324
325 __ Bind(&ok); 325 __ Bind(&ok);
326 GenerateTailCallToSharedCode(masm); 326 GenerateTailCallToSharedCode(masm);
327 } 327 }
328 328
329 329
330 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 330 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
331 bool is_api_function, 331 bool is_api_function,
332 bool count_constructions) { 332 bool count_constructions,
333 bool create_memento) {
333 // ----------- S t a t e ------------- 334 // ----------- S t a t e -------------
334 // -- x0 : number of arguments 335 // -- x0 : number of arguments
335 // -- x1 : constructor function 336 // -- x1 : constructor function
337 // -- x2 : allocation site or undefined
336 // -- lr : return address 338 // -- lr : return address
337 // -- sp[...]: constructor arguments 339 // -- sp[...]: constructor arguments
338 // ----------------------------------- 340 // -----------------------------------
339 341
340 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); 342 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper");
341 // Should never count constructions for api objects. 343 // Should never count constructions for api objects.
342 ASSERT(!is_api_function || !count_constructions); 344 ASSERT(!is_api_function || !count_constructions);
345 // Should never create mementos for api functions.
346 ASSERT(!is_api_function || !create_memento);
347 // Should never create mementos before slack tracking is finished.
348 ASSERT(!count_constructions || !create_memento);
343 349
344 Isolate* isolate = masm->isolate(); 350 Isolate* isolate = masm->isolate();
345 351
346 // Enter a construct frame. 352 // Enter a construct frame.
347 { 353 {
348 FrameScope scope(masm, StackFrame::CONSTRUCT); 354 FrameScope scope(masm, StackFrame::CONSTRUCT);
349 355
350 // Preserve the two incoming parameters on the stack. 356 // Preserve the three incoming parameters on the stack.
357 if (create_memento) {
358 __ AssertUndefinedOrAllocationSite(x2, x10);
359 __ Push(x2);
360 }
361
351 Register argc = x0; 362 Register argc = x0;
352 Register constructor = x1; 363 Register constructor = x1;
353 // x1: constructor function 364 // x1: constructor function
354 __ SmiTag(argc); 365 __ SmiTag(argc);
355 __ Push(argc, constructor); 366 __ Push(argc, constructor);
356 // sp[0] : Constructor function. 367 // sp[0] : Constructor function.
357 // sp[1]: number of arguments (smi-tagged) 368 // sp[1]: number of arguments (smi-tagged)
358 369
359 // Try to allocate the object without transitioning into C code. If any of 370 // Try to allocate the object without transitioning into C code. If any of
360 // the preconditions is not met, the code bails out to the runtime call. 371 // 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
400 // The call will replace the stub, so the countdown is only done once. 411 // The call will replace the stub, so the countdown is only done once.
401 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); 412 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
402 __ Pop(init_map, constructor); 413 __ Pop(init_map, constructor);
403 __ Bind(&allocate); 414 __ Bind(&allocate);
404 } 415 }
405 416
406 // Now allocate the JSObject on the heap. 417 // Now allocate the JSObject on the heap.
407 Register obj_size = x3; 418 Register obj_size = x3;
408 Register new_obj = x4; 419 Register new_obj = x4;
409 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); 420 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset));
410 __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); 421 if (create_memento) {
422 __ Add(x7, obj_size,
423 Operand(AllocationMemento::kSize / kPointerSize));
424 __ Allocate(x7, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS);
425 } else {
426 __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS);
427 }
411 428
412 // Allocated the JSObject, now initialize the fields. Map is set to 429 // Allocated the JSObject, now initialize the fields. Map is set to
413 // initial map and properties and elements are set to empty fixed array. 430 // initial map and properties and elements are set to empty fixed array.
414 // NB. the object pointer is not tagged, so MemOperand is used. 431 // NB. the object pointer is not tagged, so MemOperand is used.
415 Register empty = x5; 432 Register empty = x5;
416 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); 433 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
417 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); 434 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset));
418 __ Str(empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); 435 __ Str(empty, MemOperand(new_obj, JSObject::kPropertiesOffset));
419 __ Str(empty, MemOperand(new_obj, JSObject::kElementsOffset)); 436 __ Str(empty, MemOperand(new_obj, JSObject::kElementsOffset));
420 437
(...skipping 30 matching lines...) Expand all
451 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); 468 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
452 } 469 }
453 __ InitializeFieldsWithFiller(first_prop, first_non_prealloc, undef); 470 __ InitializeFieldsWithFiller(first_prop, first_non_prealloc, undef);
454 // To allow for truncation. 471 // To allow for truncation.
455 __ LoadRoot(x12, Heap::kOnePointerFillerMapRootIndex); 472 __ LoadRoot(x12, Heap::kOnePointerFillerMapRootIndex);
456 __ InitializeFieldsWithFiller(first_prop, obj_end, x12); 473 __ InitializeFieldsWithFiller(first_prop, obj_end, x12);
457 } else { 474 } else {
458 __ InitializeFieldsWithFiller(first_prop, obj_end, undef); 475 __ InitializeFieldsWithFiller(first_prop, obj_end, undef);
459 } 476 }
460 477
478 if (create_memento) {
mvstanton 2014/02/19 08:40:26 Hannes, I've changed this snippet of code to fit t
479 // It's important that first_prop (x5) contains new space top in order
480 // to satisfy the RESULT_CONTAINS_TOP flag in the Allocate statement
481 // below. Therefore the memento is initialized continuing the
482 // post-increment style of the JSObject fields before.
483 __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex);
484 ASSERT_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
485 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
486 // Load the AllocationSite
487 __ Peek(x14, 2 * kXRegSizeInBytes);
488 ASSERT_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
489 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
490 }
491
461 // Add the object tag to make the JSObject real, so that we can continue 492 // Add the object tag to make the JSObject real, so that we can continue
462 // and jump into the continuation code at any time from now on. Any 493 // and jump into the continuation code at any time from now on. Any
463 // failures need to undo the allocation, so that the heap is in a 494 // failures need to undo the allocation, so that the heap is in a
464 // consistent state and verifiable. 495 // consistent state and verifiable.
465 __ Add(new_obj, new_obj, kHeapObjectTag); 496 __ Add(new_obj, new_obj, kHeapObjectTag);
466 497
467 // Check if a non-empty properties array is needed. Continue with 498 // Check if a non-empty properties array is needed. Continue with
468 // allocated object if not, or fall through to runtime call if it is. 499 // allocated object if not, or fall through to runtime call if it is.
469 Register element_count = x3; 500 Register element_count = x3;
470 __ Ldrb(x3, FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset)); 501 __ Ldrb(x3, FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 541
511 // Undo the setting of the new top so that the heap is verifiable. For 542 // Undo the setting of the new top so that the heap is verifiable. For
512 // example, the map's unused properties potentially do not match the 543 // example, the map's unused properties potentially do not match the
513 // allocated objects unused properties. 544 // allocated objects unused properties.
514 __ Bind(&undo_allocation); 545 __ Bind(&undo_allocation);
515 __ UndoAllocationInNewSpace(new_obj, x14); 546 __ UndoAllocationInNewSpace(new_obj, x14);
516 } 547 }
517 548
518 // Allocate the new receiver object using the runtime call. 549 // Allocate the new receiver object using the runtime call.
519 __ Bind(&rt_call); 550 __ Bind(&rt_call);
520 __ Push(constructor); // Argument for Runtime_NewObject. 551 Label count_incremented;
521 __ CallRuntime(Runtime::kNewObject, 1); 552 if (create_memento) {
522 __ Mov(x4, x0); 553 // Get the cell or allocation site.
554 __ Peek(x4, 2 * kXRegSizeInBytes);
555 __ Push(x4);
556 __ Push(constructor); // Argument for Runtime_NewObject.
557 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2);
558 __ Mov(x4, x0);
559 // If we ended up using the runtime, and we want a memento, then the
560 // runtime call made it for us, and we shouldn't do create count
561 // increment.
562 __ jmp(&count_incremented);
563 } else {
564 __ Push(constructor); // Argument for Runtime_NewObject.
565 __ CallRuntime(Runtime::kNewObject, 1);
566 __ Mov(x4, x0);
567 }
523 568
524 // Receiver for constructor call allocated. 569 // Receiver for constructor call allocated.
525 // x4: JSObject 570 // x4: JSObject
526 __ Bind(&allocated); 571 __ Bind(&allocated);
572
573 if (create_memento) {
574 __ Peek(x10, 2 * kXRegSizeInBytes);
575 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented);
576 // r2 is an AllocationSite. We are creating a memento from it, so we
577 // need to increment the memento create count.
578 __ Ldr(x5, FieldMemOperand(x10,
579 AllocationSite::kPretenureCreateCountOffset));
580 __ Add(x5, x5, Operand(Smi::FromInt(1)));
581 __ Str(x5, FieldMemOperand(x10,
582 AllocationSite::kPretenureCreateCountOffset));
583 __ bind(&count_incremented);
Hannes Payer (out of office) 2014/02/18 16:24:26 bind outside if?
584 }
585
527 __ Push(x4, x4); 586 __ Push(x4, x4);
528 587
529 // Reload the number of arguments from the stack. 588 // Reload the number of arguments from the stack.
530 // Set it up in x0 for the function call below. 589 // Set it up in x0 for the function call below.
531 // jssp[0]: receiver 590 // jssp[0]: receiver
532 // jssp[1]: receiver 591 // jssp[1]: receiver
533 // jssp[2]: constructor function 592 // jssp[2]: constructor function
534 // jssp[3]: number of arguments (smi-tagged) 593 // jssp[3]: number of arguments (smi-tagged)
535 __ Peek(constructor, 2 * kXRegSizeInBytes); // Load constructor. 594 __ Peek(constructor, 2 * kXRegSizeInBytes); // Load constructor.
536 __ Peek(argc, 3 * kXRegSizeInBytes); // Load number of arguments. 595 __ Peek(argc, 3 * kXRegSizeInBytes); // Load number of arguments.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 } 682 }
624 683
625 __ DropBySMI(x1); 684 __ DropBySMI(x1);
626 __ Drop(1); 685 __ Drop(1);
627 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); 686 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2);
628 __ Ret(); 687 __ Ret();
629 } 688 }
630 689
631 690
632 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { 691 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
633 Generate_JSConstructStubHelper(masm, false, true); 692 Generate_JSConstructStubHelper(masm, false, true, false);
634 } 693 }
635 694
636 695
637 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 696 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
638 Generate_JSConstructStubHelper(masm, false, false); 697 Generate_JSConstructStubHelper(masm, false, false, true);
639 } 698 }
640 699
641 700
642 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 701 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
643 Generate_JSConstructStubHelper(masm, true, false); 702 Generate_JSConstructStubHelper(masm, true, false, false);
644 } 703 }
645 704
646 705
647 // Input: 706 // Input:
648 // x0: code entry. 707 // x0: code entry.
649 // x1: function. 708 // x1: function.
650 // x2: receiver. 709 // x2: receiver.
651 // x3: argc. 710 // x3: argc.
652 // x4: argv. 711 // x4: argv.
653 // Output: 712 // Output:
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 __ Bind(&dont_adapt_arguments); 1531 __ Bind(&dont_adapt_arguments);
1473 __ Jump(x3); 1532 __ Jump(x3);
1474 } 1533 }
1475 1534
1476 1535
1477 #undef __ 1536 #undef __
1478 1537
1479 } } // namespace v8::internal 1538 } } // namespace v8::internal
1480 1539
1481 #endif // V8_TARGET_ARCH_ARM 1540 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/a64/code-stubs-a64.cc » ('j') | src/a64/code-stubs-a64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698