| 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);
|
|
|