Chromium Code Reviews| Index: src/a64/builtins-a64.cc |
| diff --git a/src/a64/builtins-a64.cc b/src/a64/builtins-a64.cc |
| index 34156b31621db9a192668da50eaf3e8b3bcd7ae7..e2aba9ce9e0b7abb1c373fae4c1c83edb959dbe7 100644 |
| --- a/src/a64/builtins-a64.cc |
| +++ b/src/a64/builtins-a64.cc |
| @@ -329,10 +329,12 @@ void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) { |
| static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| bool is_api_function, |
| - bool count_constructions) { |
| + bool count_constructions, |
| + bool create_memento) { |
| // ----------- S t a t e ------------- |
| // -- x0 : number of arguments |
| // -- x1 : constructor function |
| + // -- x2 : allocation site or undefined |
| // -- lr : return address |
| // -- sp[...]: constructor arguments |
| // ----------------------------------- |
| @@ -340,6 +342,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); |
| // Should never count constructions for api objects. |
| ASSERT(!is_api_function || !count_constructions); |
| + // Should never create mementos for api functions. |
| + ASSERT(!is_api_function || !create_memento); |
| + // Should never create mementos before slack tracking is finished. |
| + ASSERT(!count_constructions || !create_memento); |
| Isolate* isolate = masm->isolate(); |
| @@ -347,7 +353,12 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| { |
| FrameScope scope(masm, StackFrame::CONSTRUCT); |
| - // Preserve the two incoming parameters on the stack. |
| + // Preserve the three incoming parameters on the stack. |
| + if (create_memento) { |
| + __ AssertUndefinedOrAllocationSite(x2, x10); |
| + __ Push(x2); |
| + } |
| + |
| Register argc = x0; |
| Register constructor = x1; |
| // x1: constructor function |
| @@ -407,7 +418,13 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| Register obj_size = x3; |
| Register new_obj = x4; |
| __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); |
| - __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); |
| + if (create_memento) { |
| + __ Add(x7, obj_size, |
| + Operand(AllocationMemento::kSize / kPointerSize)); |
| + __ Allocate(x7, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); |
| + } else { |
| + __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); |
| + } |
| // Allocated the JSObject, now initialize the fields. Map is set to |
| // initial map and properties and elements are set to empty fixed array. |
| @@ -458,6 +475,20 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| __ InitializeFieldsWithFiller(first_prop, obj_end, undef); |
| } |
| + if (create_memento) { |
|
mvstanton
2014/02/19 08:40:26
Hannes, I've changed this snippet of code to fit t
|
| + // It's important that first_prop (x5) contains new space top in order |
| + // to satisfy the RESULT_CONTAINS_TOP flag in the Allocate statement |
| + // below. Therefore the memento is initialized continuing the |
| + // post-increment style of the JSObject fields before. |
| + __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex); |
| + ASSERT_EQ(0 * kPointerSize, AllocationMemento::kMapOffset); |
| + __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); |
| + // Load the AllocationSite |
| + __ Peek(x14, 2 * kXRegSizeInBytes); |
| + ASSERT_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset); |
| + __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); |
| + } |
| + |
| // Add the object tag to make the JSObject real, so that we can continue |
| // and jump into the continuation code at any time from now on. Any |
| // failures need to undo the allocation, so that the heap is in a |
| @@ -517,13 +548,41 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| // Allocate the new receiver object using the runtime call. |
| __ Bind(&rt_call); |
| - __ Push(constructor); // Argument for Runtime_NewObject. |
| - __ CallRuntime(Runtime::kNewObject, 1); |
| - __ Mov(x4, x0); |
| + Label count_incremented; |
| + if (create_memento) { |
| + // Get the cell or allocation site. |
| + __ Peek(x4, 2 * kXRegSizeInBytes); |
| + __ Push(x4); |
| + __ Push(constructor); // Argument for Runtime_NewObject. |
| + __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2); |
| + __ Mov(x4, x0); |
| + // If we ended up using the runtime, and we want a memento, then the |
| + // runtime call made it for us, and we shouldn't do create count |
| + // increment. |
| + __ jmp(&count_incremented); |
| + } else { |
| + __ Push(constructor); // Argument for Runtime_NewObject. |
| + __ CallRuntime(Runtime::kNewObject, 1); |
| + __ Mov(x4, x0); |
| + } |
| // Receiver for constructor call allocated. |
| // x4: JSObject |
| __ Bind(&allocated); |
| + |
| + if (create_memento) { |
| + __ Peek(x10, 2 * kXRegSizeInBytes); |
| + __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); |
| + // r2 is an AllocationSite. We are creating a memento from it, so we |
| + // need to increment the memento create count. |
| + __ Ldr(x5, FieldMemOperand(x10, |
| + AllocationSite::kPretenureCreateCountOffset)); |
| + __ Add(x5, x5, Operand(Smi::FromInt(1))); |
| + __ Str(x5, FieldMemOperand(x10, |
| + AllocationSite::kPretenureCreateCountOffset)); |
| + __ bind(&count_incremented); |
|
Hannes Payer (out of office)
2014/02/18 16:24:26
bind outside if?
|
| + } |
| + |
| __ Push(x4, x4); |
| // Reload the number of arguments from the stack. |
| @@ -630,17 +689,17 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { |
| - Generate_JSConstructStubHelper(masm, false, true); |
| + Generate_JSConstructStubHelper(masm, false, true, false); |
| } |
| void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
| - Generate_JSConstructStubHelper(masm, false, false); |
| + Generate_JSConstructStubHelper(masm, false, false, true); |
| } |
| void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| - Generate_JSConstructStubHelper(masm, true, false); |
| + Generate_JSConstructStubHelper(masm, true, false, false); |
| } |