Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 6686003: Refactor fast API call. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Next round Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1964 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 Object* obj; 1975 Object* obj;
1976 { MaybeObject* maybe_obj = GenerateMissBranch(); 1976 { MaybeObject* maybe_obj = GenerateMissBranch();
1977 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1977 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1978 } 1978 }
1979 1979
1980 // Return the generated code. 1980 // Return the generated code.
1981 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 1981 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
1982 } 1982 }
1983 1983
1984 1984
1985 MaybeObject* CallStubCompiler::CompileFastApiCall(
1986 const CallOptimization& optimization,
1987 Object* object,
1988 JSObject* holder,
1989 JSGlobalPropertyCell* cell,
1990 JSFunction* function,
1991 String* name) {
1992 ASSERT(optimization.is_simple_api_call());
1993 // Bail out if object is a global object as we don't want to
1994 // repatch it to global receiver.
1995 if (object->IsGlobalObject()) return Heap::undefined_value();
1996 if (cell != NULL) return Heap::undefined_value();
1997 int depth = optimization.GetPrototypeDepthOfExpectedType(
1998 JSObject::cast(object), holder);
1999 if (depth == kInvalidProtoDepth) return Heap::undefined_value();
2000
2001 Label miss, miss_before_stack_reserved;
2002
2003 GenerateNameCheck(name, &miss_before_stack_reserved);
2004
2005 // Get the receiver from the stack.
2006 const int argc = arguments().immediate();
2007 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2008
2009 // Check that the receiver isn't a smi.
2010 __ JumpIfSmi(rdx, &miss_before_stack_reserved);
2011
2012 __ IncrementCounter(&Counters::call_const, 1);
2013 __ IncrementCounter(&Counters::call_const_fast_api, 1);
2014
2015 // Allocate space for v8::Arguments implicit values. Must be initialized
2016 // before calling any runtime function.
2017 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2018
2019 // Check that the maps haven't changed and find a Holder as a side effect.
2020 CheckPrototypes(JSObject::cast(object), rdx, holder,
2021 rbx, rax, rdi, name, depth, &miss);
2022
2023 // Move the return address on top of the stack.
2024 __ movq(rax, Operand(rsp, 3 * kPointerSize));
2025 __ movq(Operand(rsp, 0 * kPointerSize), rax);
2026
2027 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2028 if (result->IsFailure()) return result;
2029
2030 __ bind(&miss);
2031 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2032
2033 __ bind(&miss_before_stack_reserved);
2034 Object* obj;
2035 { MaybeObject* maybe_obj = GenerateMissBranch();
2036 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2037 }
2038
2039 // Return the generated code.
2040 return GetCode(function);
2041 }
2042
2043
1985 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, 2044 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
1986 JSObject* holder, 2045 JSObject* holder,
1987 JSFunction* function, 2046 JSFunction* function,
1988 String* name, 2047 String* name,
1989 CheckType check) { 2048 CheckType check) {
1990 // ----------- S t a t e ------------- 2049 // ----------- S t a t e -------------
1991 // rcx : function name 2050 // rcx : function name
1992 // rsp[0] : return address 2051 // rsp[0] : return address
1993 // rsp[8] : argument argc 2052 // rsp[8] : argument argc
1994 // rsp[16] : argument argc - 1 2053 // rsp[16] : argument argc - 1
1995 // ... 2054 // ...
1996 // rsp[argc * 8] : argument 1 2055 // rsp[argc * 8] : argument 1
1997 // rsp[(argc + 1) * 8] : argument 0 = receiver 2056 // rsp[(argc + 1) * 8] : argument 0 = receiver
1998 // ----------------------------------- 2057 // -----------------------------------
1999 2058
2000 SharedFunctionInfo* function_info = function->shared(); 2059 if (HasCustomCallGenerator(function)) {
2001 if (function_info->HasBuiltinFunctionId()) {
2002 BuiltinFunctionId id = function_info->builtin_function_id();
2003 MaybeObject* maybe_result = CompileCustomCall( 2060 MaybeObject* maybe_result = CompileCustomCall(
2004 id, object, holder, NULL, function, name); 2061 object, holder, NULL, function, name);
2005 Object* result; 2062 Object* result;
2006 if (!maybe_result->ToObject(&result)) return maybe_result; 2063 if (!maybe_result->ToObject(&result)) return maybe_result;
2007 // undefined means bail out to regular compiler. 2064 // undefined means bail out to regular compiler.
2008 if (!result->IsUndefined()) return result; 2065 if (!result->IsUndefined()) return result;
2009 } 2066 }
2010 2067
2011 Label miss_in_smi_check; 2068 Label miss;
2012 2069
2013 GenerateNameCheck(name, &miss_in_smi_check); 2070 GenerateNameCheck(name, &miss);
2014 2071
2015 // Get the receiver from the stack. 2072 // Get the receiver from the stack.
2016 const int argc = arguments().immediate(); 2073 const int argc = arguments().immediate();
2017 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2074 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2018 2075
2019 // Check that the receiver isn't a smi. 2076 // Check that the receiver isn't a smi.
2020 if (check != NUMBER_CHECK) { 2077 if (check != NUMBER_CHECK) {
2021 __ JumpIfSmi(rdx, &miss_in_smi_check); 2078 __ JumpIfSmi(rdx, &miss);
2022 } 2079 }
2023 2080
2024 // Make sure that it's okay not to patch the on stack receiver 2081 // Make sure that it's okay not to patch the on stack receiver
2025 // unless we're doing a receiver map check. 2082 // unless we're doing a receiver map check.
2026 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2083 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2027 2084
2028 CallOptimization optimization(function); 2085 SharedFunctionInfo* function_info = function->shared();
2029 int depth = kInvalidProtoDepth;
2030 Label miss;
2031
2032 switch (check) { 2086 switch (check) {
2033 case RECEIVER_MAP_CHECK: 2087 case RECEIVER_MAP_CHECK:
2034 __ IncrementCounter(&Counters::call_const, 1); 2088 __ IncrementCounter(&Counters::call_const, 1);
2035 2089
2036 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) {
2037 depth = optimization.GetPrototypeDepthOfExpectedType(
2038 JSObject::cast(object), holder);
2039 }
2040
2041 if (depth != kInvalidProtoDepth) {
2042 __ IncrementCounter(&Counters::call_const_fast_api, 1);
2043
2044 // Allocate space for v8::Arguments implicit values. Must be initialized
2045 // before to call any runtime function.
2046 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2047 }
2048
2049 // Check that the maps haven't changed. 2090 // Check that the maps haven't changed.
2050 CheckPrototypes(JSObject::cast(object), rdx, holder, 2091 CheckPrototypes(JSObject::cast(object), rdx, holder,
2051 rbx, rax, rdi, name, depth, &miss); 2092 rbx, rax, rdi, name, &miss);
2052 2093
2053 // Patch the receiver on the stack with the global proxy if 2094 // Patch the receiver on the stack with the global proxy if
2054 // necessary. 2095 // necessary.
2055 if (object->IsGlobalObject()) { 2096 if (object->IsGlobalObject()) {
2056 ASSERT(depth == kInvalidProtoDepth);
2057 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2097 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2058 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2098 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
2059 } 2099 }
2060 break; 2100 break;
2061 2101
2062 case STRING_CHECK: 2102 case STRING_CHECK:
2063 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2103 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2064 // Calling non-strict non-builtins with a value as the receiver 2104 // Calling non-strict non-builtins with a value as the receiver
2065 // requires boxing. 2105 // requires boxing.
2066 __ jmp(&miss); 2106 __ jmp(&miss);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 2156 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
2117 rbx, rdx, rdi, name, &miss); 2157 rbx, rdx, rdi, name, &miss);
2118 } 2158 }
2119 break; 2159 break;
2120 } 2160 }
2121 2161
2122 default: 2162 default:
2123 UNREACHABLE(); 2163 UNREACHABLE();
2124 } 2164 }
2125 2165
2126 if (depth != kInvalidProtoDepth) { 2166 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
2127 // Move the return address on top of the stack.
2128 __ movq(rax, Operand(rsp, 3 * kPointerSize));
2129 __ movq(Operand(rsp, 0 * kPointerSize), rax);
2130
2131 // rsp[2 * kPointerSize] is uninitialized, rsp[3 * kPointerSize] contains
2132 // duplicate of return address and will be overwritten.
2133 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2134 if (result->IsFailure()) return result;
2135 } else {
2136 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
2137 }
2138 2167
2139 // Handle call cache miss. 2168 // Handle call cache miss.
2140 __ bind(&miss); 2169 __ bind(&miss);
2141 if (depth != kInvalidProtoDepth) {
2142 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2143 }
2144
2145 // Handle call cache miss.
2146 __ bind(&miss_in_smi_check);
2147 Object* obj; 2170 Object* obj;
2148 { MaybeObject* maybe_obj = GenerateMissBranch(); 2171 { MaybeObject* maybe_obj = GenerateMissBranch();
2149 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2172 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2150 } 2173 }
2151 2174
2152 // Return the generated code. 2175 // Return the generated code.
2153 return GetCode(function); 2176 return GetCode(function);
2154 } 2177 }
2155 2178
2156 2179
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 // ----------- S t a t e ------------- 2254 // ----------- S t a t e -------------
2232 // rcx : function name 2255 // rcx : function name
2233 // rsp[0] : return address 2256 // rsp[0] : return address
2234 // rsp[8] : argument argc 2257 // rsp[8] : argument argc
2235 // rsp[16] : argument argc - 1 2258 // rsp[16] : argument argc - 1
2236 // ... 2259 // ...
2237 // rsp[argc * 8] : argument 1 2260 // rsp[argc * 8] : argument 1
2238 // rsp[(argc + 1) * 8] : argument 0 = receiver 2261 // rsp[(argc + 1) * 8] : argument 0 = receiver
2239 // ----------------------------------- 2262 // -----------------------------------
2240 2263
2241 SharedFunctionInfo* function_info = function->shared(); 2264 if (HasCustomCallGenerator(function)) {
2242 if (function_info->HasBuiltinFunctionId()) {
2243 BuiltinFunctionId id = function_info->builtin_function_id();
2244 MaybeObject* maybe_result = CompileCustomCall( 2265 MaybeObject* maybe_result = CompileCustomCall(
2245 id, object, holder, cell, function, name); 2266 object, holder, cell, function, name);
2246 Object* result; 2267 Object* result;
2247 if (!maybe_result->ToObject(&result)) return maybe_result; 2268 if (!maybe_result->ToObject(&result)) return maybe_result;
2248 // undefined means bail out to regular compiler. 2269 // undefined means bail out to regular compiler.
2249 if (!result->IsUndefined()) return result; 2270 if (!result->IsUndefined()) return result;
2250 } 2271 }
2251 2272
2252 Label miss; 2273 Label miss;
2253 2274
2254 GenerateNameCheck(name, &miss); 2275 GenerateNameCheck(name, &miss);
2255 2276
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
2953 2974
2954 // Return the generated code. 2975 // Return the generated code.
2955 return GetCode(CALLBACKS, name); 2976 return GetCode(CALLBACKS, name);
2956 } 2977 }
2957 2978
2958 2979
2959 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { 2980 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
2960 // ----------- S t a t e ------------- 2981 // ----------- S t a t e -------------
2961 // -- rax : key 2982 // -- rax : key
2962 // -- rdx : receiver 2983 // -- rdx : receiver
2963 // -- esp[0] : return address 2984 // -- rsp[0] : return address
2964 // ----------------------------------- 2985 // -----------------------------------
2965 Label miss; 2986 Label miss;
2966 2987
2967 // Check that the receiver isn't a smi. 2988 // Check that the receiver isn't a smi.
2968 __ JumpIfSmi(rdx, &miss); 2989 __ JumpIfSmi(rdx, &miss);
2969 2990
2970 // Check that the map matches. 2991 // Check that the map matches.
2971 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), 2992 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
2972 Handle<Map>(receiver->map())); 2993 Handle<Map>(receiver->map()));
2973 __ j(not_equal, &miss); 2994 __ j(not_equal, &miss);
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
3423 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); 3444 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
3424 3445
3425 return GetCode(flags); 3446 return GetCode(flags);
3426 } 3447 }
3427 3448
3428 #undef __ 3449 #undef __
3429 3450
3430 } } // namespace v8::internal 3451 } } // namespace v8::internal
3431 3452
3432 #endif // V8_TARGET_ARCH_X64 3453 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/stub-cache.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698