Index: src/x64/stub-cache-x64.cc |
=================================================================== |
--- src/x64/stub-cache-x64.cc (revision 6384) |
+++ src/x64/stub-cache-x64.cc (working copy) |
@@ -1327,8 +1327,8 @@ |
MaybeObject* CallStubCompiler::GenerateMissBranch() { |
- MaybeObject* maybe_obj = |
- StubCache::ComputeCallMiss(arguments().immediate(), kind_); |
+ MaybeObject* maybe_obj = StubCache::ComputeCallMiss(arguments().immediate(), |
+ kind_); |
Object* obj; |
if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
__ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
@@ -1660,10 +1660,16 @@ |
const int argc = arguments().immediate(); |
Label miss; |
+ Label name_miss; |
Label index_out_of_range; |
+ Label* index_out_of_range_label = &index_out_of_range; |
- GenerateNameCheck(name, &miss); |
+ if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
+ index_out_of_range_label = &miss; |
+ } |
+ GenerateNameCheck(name, &name_miss); |
+ |
// Check that the maps starting from the prototype haven't changed. |
GenerateDirectLoadGlobalFunctionPrototype(masm(), |
Context::STRING_FUNCTION_INDEX, |
@@ -1690,7 +1696,7 @@ |
result, |
&miss, // When not a string. |
&miss, // When not a number. |
- &index_out_of_range, |
+ index_out_of_range_label, |
STRING_INDEX_IS_NUMBER); |
char_code_at_generator.GenerateFast(masm()); |
__ ret((argc + 1) * kPointerSize); |
@@ -1698,11 +1704,16 @@ |
StubRuntimeCallHelper call_helper; |
char_code_at_generator.GenerateSlow(masm(), call_helper); |
- __ bind(&index_out_of_range); |
- __ LoadRoot(rax, Heap::kNanValueRootIndex); |
- __ ret((argc + 1) * kPointerSize); |
+ if (index_out_of_range.is_linked()) { |
+ __ bind(&index_out_of_range); |
+ __ LoadRoot(rax, Heap::kNanValueRootIndex); |
+ __ ret((argc + 1) * kPointerSize); |
+ } |
__ bind(&miss); |
+ // Restore function name in rcx. |
+ __ Move(rcx, Handle<String>(name)); |
+ __ bind(&name_miss); |
Object* obj; |
{ MaybeObject* maybe_obj = GenerateMissBranch(); |
if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
@@ -1733,10 +1744,16 @@ |
const int argc = arguments().immediate(); |
Label miss; |
+ Label name_miss; |
Label index_out_of_range; |
+ Label* index_out_of_range_label = &index_out_of_range; |
- GenerateNameCheck(name, &miss); |
+ if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
+ index_out_of_range_label = &miss; |
+ } |
+ GenerateNameCheck(name, &name_miss); |
+ |
// Check that the maps starting from the prototype haven't changed. |
GenerateDirectLoadGlobalFunctionPrototype(masm(), |
Context::STRING_FUNCTION_INDEX, |
@@ -1765,7 +1782,7 @@ |
result, |
&miss, // When not a string. |
&miss, // When not a number. |
- &index_out_of_range, |
+ index_out_of_range_label, |
STRING_INDEX_IS_NUMBER); |
char_at_generator.GenerateFast(masm()); |
__ ret((argc + 1) * kPointerSize); |
@@ -1773,11 +1790,16 @@ |
StubRuntimeCallHelper call_helper; |
char_at_generator.GenerateSlow(masm(), call_helper); |
- __ bind(&index_out_of_range); |
- __ LoadRoot(rax, Heap::kEmptyStringRootIndex); |
- __ ret((argc + 1) * kPointerSize); |
+ if (index_out_of_range.is_linked()) { |
+ __ bind(&index_out_of_range); |
+ __ LoadRoot(rax, Heap::kEmptyStringRootIndex); |
+ __ ret((argc + 1) * kPointerSize); |
+ } |
__ bind(&miss); |
+ // Restore function name in rcx. |
+ __ Move(rcx, Handle<String>(name)); |
+ __ bind(&name_miss); |
Object* obj; |
{ MaybeObject* maybe_obj = GenerateMissBranch(); |
if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
@@ -2262,17 +2284,24 @@ |
__ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
} |
- // Setup the context (function already in edi). |
+ // Setup the context (function already in rdi). |
__ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
// Jump to the cached code (tail call). |
__ IncrementCounter(&Counters::call_global_inline, 1); |
ASSERT(function->is_compiled()); |
- Handle<Code> code(function->code()); |
ParameterCount expected(function->shared()->formal_parameter_count()); |
- __ InvokeCode(code, expected, arguments(), |
- RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
- |
+ if (V8::UseCrankshaft()) { |
+ // TODO(kasperl): For now, we always call indirectly through the |
+ // code field in the function to allow recompilation to take effect |
+ // without changing any of the call sites. |
+ __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
+ __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION); |
+ } else { |
+ Handle<Code> code(function->code()); |
+ __ InvokeCode(code, expected, arguments(), |
+ RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
+ } |
// Handle call cache miss. |
__ bind(&miss); |
__ IncrementCounter(&Counters::call_global_inline_miss, 1); |