From 01e0e6c662d678599d044857df8d6dba880b5b95 Mon Sep 17 00:00:00 2001 From: "vitalyr@chromium.org" Date: Tue, 24 Aug 2010 13:39:29 +0000 Subject: [PATCH] Ported string call IC-s to x64. Review URL: http://codereview.chromium.org/3156045 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5330 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/stub-cache-x64.cc | 128 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 5 deletions(-) diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index e0644cd63b..e4ab2325ad 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -1291,8 +1291,69 @@ Object* CallStubCompiler::CompileStringCharAtCall(Object* object, JSFunction* function, String* name, CheckType check) { - // TODO(722): implement this. - return Heap::undefined_value(); + // ----------- S t a t e ------------- + // -- rcx : function name + // -- rsp[0] : return address + // -- rsp[(argc - n) * 8] : arg[n] (zero-based) + // -- ... + // -- rsp[(argc + 1) * 8] : receiver + // ----------------------------------- + + // If object is not a string, bail out to regular call. + if (!object->IsString()) return Heap::undefined_value(); + + const int argc = arguments().immediate(); + + Label miss; + Label index_out_of_range; + + GenerateNameCheck(name, &miss); + + // Check that the maps starting from the prototype haven't changed. + GenerateDirectLoadGlobalFunctionPrototype(masm(), + Context::STRING_FUNCTION_INDEX, + rax); + ASSERT(object != holder); + CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, + rbx, rdx, rdi, name, &miss); + + Register receiver = rax; + Register index = rdi; + Register scratch1 = rbx; + Register scratch2 = rdx; + Register result = rax; + __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); + if (argc > 0) { + __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); + } else { + __ LoadRoot(index, Heap::kUndefinedValueRootIndex); + } + + StringCharAtGenerator char_at_generator(receiver, + index, + scratch1, + scratch2, + result, + &miss, // When not a string. + &miss, // When not a number. + &index_out_of_range, + STRING_INDEX_IS_NUMBER); + char_at_generator.GenerateFast(masm()); + __ ret((argc + 1) * kPointerSize); + + ICRuntimeCallHelper call_helper; + char_at_generator.GenerateSlow(masm(), call_helper); + + __ bind(&index_out_of_range); + __ LoadRoot(rax, Heap::kEmptyStringRootIndex); + __ ret((argc + 1) * kPointerSize); + + __ bind(&miss); + Object* obj = GenerateMissBranch(); + if (obj->IsFailure()) return obj; + + // Return the generated code. + return GetCode(function); } @@ -1301,10 +1362,67 @@ Object* CallStubCompiler::CompileStringCharCodeAtCall(Object* object, JSFunction* function, String* name, CheckType check) { - // TODO(722): implement this. - return Heap::undefined_value(); -} + // ----------- S t a t e ------------- + // -- rcx : function name + // -- rsp[0] : return address + // -- rsp[(argc - n) * 8] : arg[n] (zero-based) + // -- ... + // -- rsp[(argc + 1) * 8] : receiver + // ----------------------------------- + // If object is not a string, bail out to regular call. + if (!object->IsString()) return Heap::undefined_value(); + + const int argc = arguments().immediate(); + + Label miss; + Label index_out_of_range; + GenerateNameCheck(name, &miss); + + // Check that the maps starting from the prototype haven't changed. + GenerateDirectLoadGlobalFunctionPrototype(masm(), + Context::STRING_FUNCTION_INDEX, + rax); + ASSERT(object != holder); + CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, + rbx, rdx, rdi, name, &miss); + + Register receiver = rbx; + Register index = rdi; + Register scratch = rdx; + Register result = rax; + __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); + if (argc > 0) { + __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); + } else { + __ LoadRoot(index, Heap::kUndefinedValueRootIndex); + } + + StringCharCodeAtGenerator char_code_at_generator(receiver, + index, + scratch, + result, + &miss, // When not a string. + &miss, // When not a number. + &index_out_of_range, + STRING_INDEX_IS_NUMBER); + char_code_at_generator.GenerateFast(masm()); + __ ret((argc + 1) * kPointerSize); + + ICRuntimeCallHelper call_helper; + char_code_at_generator.GenerateSlow(masm(), call_helper); + + __ bind(&index_out_of_range); + __ LoadRoot(rax, Heap::kNanValueRootIndex); + __ ret((argc + 1) * kPointerSize); + + __ bind(&miss); + Object* obj = GenerateMissBranch(); + if (obj->IsFailure()) return obj; + + // Return the generated code. + return GetCode(function); +} Object* CallStubCompiler::CompileCallInterceptor(JSObject* object,