Commit 67265201 authored by baptiste.afsa@arm.com's avatar baptiste.afsa@arm.com

A64: Tidy up some TODOs in GenerateRecordCallTarget.

R=jochen@chromium.org

Review URL: https://codereview.chromium.org/184433002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19705 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2aefde44
...@@ -3257,15 +3257,22 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { ...@@ -3257,15 +3257,22 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
} }
// TODO(jbramley): Don't use static registers here, but take them as arguments. static void GenerateRecordCallTarget(MacroAssembler* masm,
static void GenerateRecordCallTarget(MacroAssembler* masm) { Register argc,
Register function,
Register feedback_vector,
Register index,
Register scratch1,
Register scratch2) {
ASM_LOCATION("GenerateRecordCallTarget"); ASM_LOCATION("GenerateRecordCallTarget");
ASSERT(!AreAliased(scratch1, scratch2,
argc, function, feedback_vector, index));
// Cache the called function in a feedback vector slot. Cache states are // Cache the called function in a feedback vector slot. Cache states are
// uninitialized, monomorphic (indicated by a JSFunction), and megamorphic. // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic.
// x0 : number of arguments to the construct function // argc : number of arguments to the construct function
// x1 : the function to call // function : the function to call
// x2 : feedback vector // feedback_vector : the feedback vector
// x3 : slot in feedback vector (smi) // index : slot in feedback vector (smi)
Label initialize, done, miss, megamorphic, not_array_function; Label initialize, done, miss, megamorphic, not_array_function;
ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
...@@ -3274,24 +3281,25 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { ...@@ -3274,24 +3281,25 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
masm->isolate()->heap()->the_hole_value()); masm->isolate()->heap()->the_hole_value());
// Load the cache state. // Load the cache state.
__ Add(x4, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); __ Add(scratch1, feedback_vector,
__ Ldr(x4, FieldMemOperand(x4, FixedArray::kHeaderSize)); Operand::UntagSmiAndScale(index, kPointerSizeLog2));
__ Ldr(scratch1, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
// A monomorphic cache hit or an already megamorphic state: invoke the // A monomorphic cache hit or an already megamorphic state: invoke the
// function without changing the state. // function without changing the state.
__ Cmp(x4, x1); __ Cmp(scratch1, function);
__ B(eq, &done); __ B(eq, &done);
// If we came here, we need to see if we are the array function. // If we came here, we need to see if we are the array function.
// If we didn't have a matching function, and we didn't find the megamorph // If we didn't have a matching function, and we didn't find the megamorph
// sentinel, then we have in the slot either some other function or an // sentinel, then we have in the slot either some other function or an
// AllocationSite. Do a map check on the object in ecx. // AllocationSite. Do a map check on the object in scratch1 register.
__ Ldr(x5, FieldMemOperand(x4, AllocationSite::kMapOffset)); __ Ldr(scratch2, FieldMemOperand(scratch1, AllocationSite::kMapOffset));
__ JumpIfNotRoot(x5, Heap::kAllocationSiteMapRootIndex, &miss); __ JumpIfNotRoot(scratch2, Heap::kAllocationSiteMapRootIndex, &miss);
// Make sure the function is the Array() function // Make sure the function is the Array() function
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, x4); __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch1);
__ Cmp(x1, x4); __ Cmp(function, scratch1);
__ B(ne, &megamorphic); __ B(ne, &megamorphic);
__ B(&done); __ B(&done);
...@@ -3299,21 +3307,22 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { ...@@ -3299,21 +3307,22 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// A monomorphic miss (i.e, here the cache is not uninitialized) goes // A monomorphic miss (i.e, here the cache is not uninitialized) goes
// megamorphic. // megamorphic.
__ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &initialize); __ JumpIfRoot(scratch1, Heap::kTheHoleValueRootIndex, &initialize);
// MegamorphicSentinel is an immortal immovable object (undefined) so no // MegamorphicSentinel is an immortal immovable object (undefined) so no
// write-barrier is needed. // write-barrier is needed.
__ Bind(&megamorphic); __ Bind(&megamorphic);
__ Add(x4, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); __ Add(scratch1, feedback_vector,
__ LoadRoot(x10, Heap::kUndefinedValueRootIndex); Operand::UntagSmiAndScale(index, kPointerSizeLog2));
__ Str(x10, FieldMemOperand(x4, FixedArray::kHeaderSize)); __ LoadRoot(scratch2, Heap::kUndefinedValueRootIndex);
__ Str(scratch2, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
__ B(&done); __ B(&done);
// An uninitialized cache is patched with the function or sentinel to // An uninitialized cache is patched with the function or sentinel to
// indicate the ElementsKind if function is the Array constructor. // indicate the ElementsKind if function is the Array constructor.
__ Bind(&initialize); __ Bind(&initialize);
// Make sure the function is the Array() function // Make sure the function is the Array() function
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, x4); __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch1);
__ Cmp(x1, x4); __ Cmp(function, scratch1);
__ B(ne, &not_array_function); __ B(ne, &not_array_function);
// The target function is the Array constructor, // The target function is the Array constructor,
...@@ -3323,31 +3332,31 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { ...@@ -3323,31 +3332,31 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
CreateAllocationSiteStub create_stub; CreateAllocationSiteStub create_stub;
// Arguments register must be smi-tagged to call out. // Arguments register must be smi-tagged to call out.
__ SmiTag(x0); __ SmiTag(argc);
__ Push(x0, x1, x2, x3); __ Push(argc, function, feedback_vector, index);
// CreateAllocationSiteStub expect the feedback vector in x2 and the slot
// index in x3.
ASSERT(feedback_vector.Is(x2) && index.Is(x3));
__ CallStub(&create_stub); __ CallStub(&create_stub);
__ Pop(x3, x2, x1, x0); __ Pop(index, feedback_vector, function, argc);
__ SmiUntag(x0); __ SmiUntag(argc);
} }
__ B(&done); __ B(&done);
__ Bind(&not_array_function); __ Bind(&not_array_function);
// An uninitialized cache is patched with the function. // An uninitialized cache is patched with the function.
__ Add(x4, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); __ Add(scratch1, feedback_vector,
// TODO(all): Does the value need to be left in x4? If not, FieldMemOperand Operand::UntagSmiAndScale(index, kPointerSizeLog2));
// could be used to avoid this add. __ Add(scratch1, scratch1, FixedArray::kHeaderSize - kHeapObjectTag);
__ Add(x4, x4, FixedArray::kHeaderSize - kHeapObjectTag); __ Str(function, MemOperand(scratch1, 0));
__ Str(x1, MemOperand(x4, 0));
__ Push(x4, x2, x1);
__ RecordWrite(x2, x4, x1, kLRHasNotBeenSaved, kDontSaveFPRegs,
EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ Pop(x1, x2, x4);
// TODO(all): Are x4, x2 and x1 outputs? This isn't clear. __ Push(function);
__ RecordWrite(feedback_vector, scratch1, function, kLRHasNotBeenSaved,
kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ Pop(function);
__ Bind(&done); __ Bind(&done);
} }
...@@ -3375,7 +3384,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -3375,7 +3384,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow);
if (RecordCallTarget()) { if (RecordCallTarget()) {
GenerateRecordCallTarget(masm); GenerateRecordCallTarget(masm, x0, function, cache_cell, slot, x4, x5);
} }
} }
...@@ -3480,7 +3489,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) { ...@@ -3480,7 +3489,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
&slow); &slow);
if (RecordCallTarget()) { if (RecordCallTarget()) {
GenerateRecordCallTarget(masm); GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5);
} }
// Jump to the function-specific construct stub. // Jump to the function-specific construct stub.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment