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

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

Issue 6815029: Merge (7180:7265] from bleeding_edge to the experimental/gc branch.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 8 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/ia32/lithium-ia32.cc ('k') | src/mark-compact.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 2122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2133 Object* obj; 2133 Object* obj;
2134 { MaybeObject* maybe_obj = GenerateMissBranch(); 2134 { MaybeObject* maybe_obj = GenerateMissBranch();
2135 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2135 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2136 } 2136 }
2137 2137
2138 // Return the generated code. 2138 // Return the generated code.
2139 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2139 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
2140 } 2140 }
2141 2141
2142 2142
2143 MaybeObject* CallStubCompiler::CompileFastApiCall(
2144 const CallOptimization& optimization,
2145 Object* object,
2146 JSObject* holder,
2147 JSGlobalPropertyCell* cell,
2148 JSFunction* function,
2149 String* name) {
2150 ASSERT(optimization.is_simple_api_call());
2151 // Bail out if object is a global object as we don't want to
2152 // repatch it to global receiver.
2153 if (object->IsGlobalObject()) return Heap::undefined_value();
2154 if (cell != NULL) return Heap::undefined_value();
2155 int depth = optimization.GetPrototypeDepthOfExpectedType(
2156 JSObject::cast(object), holder);
2157 if (depth == kInvalidProtoDepth) return Heap::undefined_value();
2158
2159 Label miss, miss_before_stack_reserved;
2160
2161 GenerateNameCheck(name, &miss_before_stack_reserved);
2162
2163 // Get the receiver from the stack.
2164 const int argc = arguments().immediate();
2165 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2166
2167 // Check that the receiver isn't a smi.
2168 __ test(edx, Immediate(kSmiTagMask));
2169 __ j(zero, &miss_before_stack_reserved, not_taken);
2170
2171 __ IncrementCounter(&Counters::call_const, 1);
2172 __ IncrementCounter(&Counters::call_const_fast_api, 1);
2173
2174 // Allocate space for v8::Arguments implicit values. Must be initialized
2175 // before calling any runtime function.
2176 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
2177
2178 // Check that the maps haven't changed and find a Holder as a side effect.
2179 CheckPrototypes(JSObject::cast(object), edx, holder,
2180 ebx, eax, edi, name, depth, &miss);
2181
2182 // Move the return address on top of the stack.
2183 __ mov(eax, Operand(esp, 3 * kPointerSize));
2184 __ mov(Operand(esp, 0 * kPointerSize), eax);
2185
2186 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2187 // duplicate of return address and will be overwritten.
2188 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2189 if (result->IsFailure()) return result;
2190
2191 __ bind(&miss);
2192 __ add(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
2193
2194 __ bind(&miss_before_stack_reserved);
2195 Object* obj;
2196 { MaybeObject* maybe_obj = GenerateMissBranch();
2197 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2198 }
2199
2200 // Return the generated code.
2201 return GetCode(function);
2202 }
2203
2204
2143 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, 2205 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
2144 JSObject* holder, 2206 JSObject* holder,
2145 JSFunction* function, 2207 JSFunction* function,
2146 String* name, 2208 String* name,
2147 CheckType check) { 2209 CheckType check) {
2148 // ----------- S t a t e ------------- 2210 // ----------- S t a t e -------------
2149 // -- ecx : name 2211 // -- ecx : name
2150 // -- esp[0] : return address 2212 // -- esp[0] : return address
2151 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2213 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2152 // -- ... 2214 // -- ...
2153 // -- esp[(argc + 1) * 4] : receiver 2215 // -- esp[(argc + 1) * 4] : receiver
2154 // ----------------------------------- 2216 // -----------------------------------
2155 2217
2156 SharedFunctionInfo* function_info = function->shared(); 2218 if (HasCustomCallGenerator(function)) {
2157 if (function_info->HasBuiltinFunctionId()) {
2158 BuiltinFunctionId id = function_info->builtin_function_id();
2159 MaybeObject* maybe_result = CompileCustomCall( 2219 MaybeObject* maybe_result = CompileCustomCall(
2160 id, object, holder, NULL, function, name); 2220 object, holder, NULL, function, name);
2161 Object* result; 2221 Object* result;
2162 if (!maybe_result->ToObject(&result)) return maybe_result; 2222 if (!maybe_result->ToObject(&result)) return maybe_result;
2163 // undefined means bail out to regular compiler. 2223 // undefined means bail out to regular compiler.
2164 if (!result->IsUndefined()) return result; 2224 if (!result->IsUndefined()) return result;
2165 } 2225 }
2166 2226
2167 Label miss_in_smi_check; 2227 Label miss;
2168 2228
2169 GenerateNameCheck(name, &miss_in_smi_check); 2229 GenerateNameCheck(name, &miss);
2170 2230
2171 // Get the receiver from the stack. 2231 // Get the receiver from the stack.
2172 const int argc = arguments().immediate(); 2232 const int argc = arguments().immediate();
2173 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2233 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2174 2234
2175 // Check that the receiver isn't a smi. 2235 // Check that the receiver isn't a smi.
2176 if (check != NUMBER_CHECK) { 2236 if (check != NUMBER_CHECK) {
2177 __ test(edx, Immediate(kSmiTagMask)); 2237 __ test(edx, Immediate(kSmiTagMask));
2178 __ j(zero, &miss_in_smi_check, not_taken); 2238 __ j(zero, &miss, not_taken);
2179 } 2239 }
2180 2240
2181 // Make sure that it's okay not to patch the on stack receiver 2241 // Make sure that it's okay not to patch the on stack receiver
2182 // unless we're doing a receiver map check. 2242 // unless we're doing a receiver map check.
2183 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2243 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2184 2244
2185 CallOptimization optimization(function); 2245 SharedFunctionInfo* function_info = function->shared();
2186 int depth = kInvalidProtoDepth;
2187 Label miss;
2188
2189 switch (check) { 2246 switch (check) {
2190 case RECEIVER_MAP_CHECK: 2247 case RECEIVER_MAP_CHECK:
2191 __ IncrementCounter(&Counters::call_const, 1); 2248 __ IncrementCounter(&Counters::call_const, 1);
2192 2249
2193 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) {
2194 depth = optimization.GetPrototypeDepthOfExpectedType(
2195 JSObject::cast(object), holder);
2196 }
2197
2198 if (depth != kInvalidProtoDepth) {
2199 __ IncrementCounter(&Counters::call_const_fast_api, 1);
2200
2201 // Allocate space for v8::Arguments implicit values. Must be initialized
2202 // before to call any runtime function.
2203 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
2204 }
2205
2206 // Check that the maps haven't changed. 2250 // Check that the maps haven't changed.
2207 CheckPrototypes(JSObject::cast(object), edx, holder, 2251 CheckPrototypes(JSObject::cast(object), edx, holder,
2208 ebx, eax, edi, name, depth, &miss); 2252 ebx, eax, edi, name, &miss);
2209 2253
2210 // Patch the receiver on the stack with the global proxy if 2254 // Patch the receiver on the stack with the global proxy if
2211 // necessary. 2255 // necessary.
2212 if (object->IsGlobalObject()) { 2256 if (object->IsGlobalObject()) {
2213 ASSERT(depth == kInvalidProtoDepth);
2214 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2257 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2215 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2258 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2216 } 2259 }
2217 break; 2260 break;
2218 2261
2219 case STRING_CHECK: 2262 case STRING_CHECK:
2220 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2263 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2221 // Calling non-strict non-builtins with a value as the receiver 2264 // Calling non-strict non-builtins with a value as the receiver
2222 // requires boxing. 2265 // requires boxing.
2223 __ jmp(&miss); 2266 __ jmp(&miss);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2274 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 2317 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
2275 ebx, edx, edi, name, &miss); 2318 ebx, edx, edi, name, &miss);
2276 } 2319 }
2277 break; 2320 break;
2278 } 2321 }
2279 2322
2280 default: 2323 default:
2281 UNREACHABLE(); 2324 UNREACHABLE();
2282 } 2325 }
2283 2326
2284 if (depth != kInvalidProtoDepth) { 2327 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
2285 // Move the return address on top of the stack.
2286 __ mov(eax, Operand(esp, 3 * kPointerSize));
2287 __ mov(Operand(esp, 0 * kPointerSize), eax);
2288
2289 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2290 // duplicate of return address and will be overwritten.
2291 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2292 if (result->IsFailure()) return result;
2293 } else {
2294 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
2295 }
2296 2328
2297 // Handle call cache miss. 2329 // Handle call cache miss.
2298 __ bind(&miss); 2330 __ bind(&miss);
2299 if (depth != kInvalidProtoDepth) {
2300 __ add(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
2301 }
2302 __ bind(&miss_in_smi_check);
2303 Object* obj; 2331 Object* obj;
2304 { MaybeObject* maybe_obj = GenerateMissBranch(); 2332 { MaybeObject* maybe_obj = GenerateMissBranch();
2305 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2333 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2306 } 2334 }
2307 2335
2308 // Return the generated code. 2336 // Return the generated code.
2309 return GetCode(function); 2337 return GetCode(function);
2310 } 2338 }
2311 2339
2312 2340
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 JSFunction* function, 2412 JSFunction* function,
2385 String* name) { 2413 String* name) {
2386 // ----------- S t a t e ------------- 2414 // ----------- S t a t e -------------
2387 // -- ecx : name 2415 // -- ecx : name
2388 // -- esp[0] : return address 2416 // -- esp[0] : return address
2389 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2417 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2390 // -- ... 2418 // -- ...
2391 // -- esp[(argc + 1) * 4] : receiver 2419 // -- esp[(argc + 1) * 4] : receiver
2392 // ----------------------------------- 2420 // -----------------------------------
2393 2421
2394 SharedFunctionInfo* function_info = function->shared(); 2422 if (HasCustomCallGenerator(function)) {
2395 if (function_info->HasBuiltinFunctionId()) {
2396 BuiltinFunctionId id = function_info->builtin_function_id();
2397 MaybeObject* maybe_result = CompileCustomCall( 2423 MaybeObject* maybe_result = CompileCustomCall(
2398 id, object, holder, cell, function, name); 2424 object, holder, cell, function, name);
2399 Object* result; 2425 Object* result;
2400 if (!maybe_result->ToObject(&result)) return maybe_result; 2426 if (!maybe_result->ToObject(&result)) return maybe_result;
2401 // undefined means bail out to regular compiler. 2427 // undefined means bail out to regular compiler.
2402 if (!result->IsUndefined()) return result; 2428 if (!result->IsUndefined()) return result;
2403 } 2429 }
2404 2430
2405 Label miss; 2431 Label miss;
2406 2432
2407 GenerateNameCheck(name, &miss); 2433 GenerateNameCheck(name, &miss);
2408 2434
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3672 3698
3673 return GetCode(flags); 3699 return GetCode(flags);
3674 } 3700 }
3675 3701
3676 3702
3677 #undef __ 3703 #undef __
3678 3704
3679 } } // namespace v8::internal 3705 } } // namespace v8::internal
3680 3706
3681 #endif // V8_TARGET_ARCH_IA32 3707 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/mark-compact.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698