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

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 8883011: Implement ICs for constructor calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years 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/builtins-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('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 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 2043 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 } else { 2054 } else {
2055 VisitForStackValue(expr->obj()); 2055 VisitForStackValue(expr->obj());
2056 VisitForAccumulatorValue(expr->key()); 2056 VisitForAccumulatorValue(expr->key());
2057 __ pop(edx); 2057 __ pop(edx);
2058 EmitKeyedPropertyLoad(expr); 2058 EmitKeyedPropertyLoad(expr);
2059 context()->Plug(eax); 2059 context()->Plug(eax);
2060 } 2060 }
2061 } 2061 }
2062 2062
2063 2063
2064 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2064 void FullCodeGenerator::EmitCallWithIC(CallBase* expr,
2065 Handle<Object> name, 2065 Handle<Object> name,
2066 RelocInfo::Mode mode) { 2066 RelocInfo::Mode mode) {
2067 // Code common for calls using the IC. 2067 // Code common for calls using the IC.
2068 ZoneList<Expression*>* args = expr->arguments(); 2068 ZoneList<Expression*>* args = expr->arguments();
2069 int arg_count = args->length(); 2069 int arg_count = args->length();
2070 { PreservePositionScope scope(masm()->positions_recorder()); 2070 { PreservePositionScope scope(masm()->positions_recorder());
2071 for (int i = 0; i < arg_count; i++) { 2071 for (int i = 0; i < arg_count; i++) {
2072 VisitForStackValue(args->at(i)); 2072 VisitForStackValue(args->at(i));
2073 } 2073 }
2074 __ Set(ecx, Immediate(name)); 2074 __ Set(ecx, Immediate(name));
2075 } 2075 }
2076 // Record source position of the IC call. 2076 // Record source position of the IC call.
2077 SetSourcePosition(expr->position()); 2077 SetSourcePosition(expr->position());
2078 Handle<Code> ic = 2078 Handle<Code> ic =
2079 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 2079 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
2080 __ call(ic, mode, expr->id()); 2080 __ call(ic, mode, expr->id());
2081 RecordJSReturnSite(expr); 2081 RecordJSReturnSite(expr);
2082 // Restore context register. 2082 // Restore context register.
2083 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2083 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2084 context()->Plug(eax); 2084 context()->Plug(eax);
2085 } 2085 }
2086 2086
2087 2087
2088 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2088 void FullCodeGenerator::EmitKeyedCallWithIC(CallBase* expr,
2089 Expression* key) { 2089 Expression* key,
2090 RelocInfo::Mode mode) {
2090 // Load the key. 2091 // Load the key.
2091 VisitForAccumulatorValue(key); 2092 VisitForAccumulatorValue(key);
2092 2093
2093 // Swap the name of the function and the receiver on the stack to follow 2094 // Swap the name of the function and the receiver on the stack to follow
2094 // the calling convention for call ICs. 2095 // the calling convention for call ICs.
2095 __ pop(ecx); 2096 __ pop(ecx);
2096 __ push(eax); 2097 __ push(eax);
2097 __ push(ecx); 2098 __ push(ecx);
2098 2099
2099 // Load the arguments. 2100 // Load the arguments.
2100 ZoneList<Expression*>* args = expr->arguments(); 2101 ZoneList<Expression*>* args = expr->arguments();
2101 int arg_count = args->length(); 2102 int arg_count = args->length();
2102 { PreservePositionScope scope(masm()->positions_recorder()); 2103 { PreservePositionScope scope(masm()->positions_recorder());
2103 for (int i = 0; i < arg_count; i++) { 2104 for (int i = 0; i < arg_count; i++) {
2104 VisitForStackValue(args->at(i)); 2105 VisitForStackValue(args->at(i));
2105 } 2106 }
2106 } 2107 }
2107 // Record source position of the IC call. 2108 // Record source position of the IC call.
2108 SetSourcePosition(expr->position()); 2109 SetSourcePosition(expr->position());
2109 Handle<Code> ic = 2110 Handle<Code> ic =
2110 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); 2111 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, mode);
2111 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2112 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2112 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2113 __ call(ic, mode, expr->id());
2113 RecordJSReturnSite(expr); 2114 RecordJSReturnSite(expr);
2114 // Restore context register. 2115 // Restore context register.
2115 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2116 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2116 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2117 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2117 } 2118 }
2118 2119
2119 2120
2120 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2121 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
2121 // Code common for calls using the call stub. 2122 // Code common for calls using the call stub.
2122 ZoneList<Expression*>* args = expr->arguments(); 2123 ZoneList<Expression*>* args = expr->arguments();
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 2271
2271 } else if (property != NULL) { 2272 } else if (property != NULL) {
2272 { PreservePositionScope scope(masm()->positions_recorder()); 2273 { PreservePositionScope scope(masm()->positions_recorder());
2273 VisitForStackValue(property->obj()); 2274 VisitForStackValue(property->obj());
2274 } 2275 }
2275 if (property->key()->IsPropertyName()) { 2276 if (property->key()->IsPropertyName()) {
2276 EmitCallWithIC(expr, 2277 EmitCallWithIC(expr,
2277 property->key()->AsLiteral()->handle(), 2278 property->key()->AsLiteral()->handle(),
2278 RelocInfo::CODE_TARGET); 2279 RelocInfo::CODE_TARGET);
2279 } else { 2280 } else {
2280 EmitKeyedCallWithIC(expr, property->key()); 2281 EmitKeyedCallWithIC(expr, property->key(), RelocInfo::CODE_TARGET);
2281 } 2282 }
2282 2283
2283 } else { 2284 } else {
2284 // Call to an arbitrary expression not handled specially above. 2285 // Call to an arbitrary expression not handled specially above.
2285 { PreservePositionScope scope(masm()->positions_recorder()); 2286 { PreservePositionScope scope(masm()->positions_recorder());
2286 VisitForStackValue(callee); 2287 VisitForStackValue(callee);
2287 } 2288 }
2288 // Load global receiver object. 2289 // Load global receiver object.
2289 __ mov(ebx, GlobalObjectOperand()); 2290 __ mov(ebx, GlobalObjectOperand());
2290 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2291 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2291 // Emit function call. 2292 // Emit function call.
2292 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2293 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2293 } 2294 }
2294 2295
2295 #ifdef DEBUG 2296 #ifdef DEBUG
2296 // RecordJSReturnSite should have been called. 2297 // RecordJSReturnSite should have been called.
2297 ASSERT(expr->return_is_recorded_); 2298 ASSERT(expr->return_is_recorded_);
2298 #endif 2299 #endif
2299 } 2300 }
2300 2301
2301 2302
2302 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2303 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2304 #ifdef DEBUG
2305 // We want to verify that RecordJSReturnSite gets called on all paths
2306 // through this function. Avoid early returns.
2307 expr->return_is_recorded_ = false;
2308 #endif
2309
2303 Comment cmnt(masm_, "[ CallNew"); 2310 Comment cmnt(masm_, "[ CallNew");
2311 Expression* callee = expr->expression();
2312 Property* property = callee->AsProperty();
2313
2304 // According to ECMA-262, section 11.2.2, page 44, the function 2314 // According to ECMA-262, section 11.2.2, page 44, the function
2305 // expression in new calls must be evaluated before the 2315 // expression in new calls must be evaluated before the
2306 // arguments. 2316 // arguments.
2307 2317
2308 // Push constructor on the stack. If it's not a function it's used as 2318 if (property != NULL) {
2309 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2319 // TODO(mstarzinger): This bailout is only needed because we do not use
2310 // ignored. 2320 // type feedback in Crankshaft yet.
2311 VisitForStackValue(expr->expression()); 2321 PrepareForBailout(callee, TOS_REG);
2322 { PreservePositionScope scope(masm()->positions_recorder());
2323 VisitForStackValue(property->obj());
2324 }
2325 if (property->key()->IsPropertyName()) {
2326 EmitCallWithIC(expr,
2327 property->key()->AsLiteral()->handle(),
2328 RelocInfo::CONSTRUCT_CALL);
2329 } else {
2330 EmitKeyedCallWithIC(expr, property->key(), RelocInfo::CONSTRUCT_CALL);
2331 }
2312 2332
2313 // Push the arguments ("left-to-right") on the stack. 2333 } else {
2314 ZoneList<Expression*>* args = expr->arguments(); 2334 // Push constructor on the stack. If it's not a function it's used as
2315 int arg_count = args->length(); 2335 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2316 for (int i = 0; i < arg_count; i++) { 2336 // ignored.
2317 VisitForStackValue(args->at(i)); 2337 VisitForStackValue(callee);
2338
2339 // Push the arguments ("left-to-right") on the stack.
2340 ZoneList<Expression*>* args = expr->arguments();
2341 int arg_count = args->length();
2342 for (int i = 0; i < arg_count; i++) {
2343 VisitForStackValue(args->at(i));
2344 }
2345
2346 // Call the construct call builtin that handles allocation and
2347 // constructor invocation.
2348 SetSourcePosition(expr->position());
2349
2350 // Load function and argument count into edi and eax.
2351 __ SafeSet(eax, Immediate(arg_count));
2352 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2353
2354 Handle<Code> construct_builtin = isolate()->builtins()->JSConstructCall();
2355 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2356 context()->Plug(eax);
2318 } 2357 }
2319
2320 // Call the construct call builtin that handles allocation and
2321 // constructor invocation.
2322 SetSourcePosition(expr->position());
2323
2324 // Load function and argument count into edi and eax.
2325 __ SafeSet(eax, Immediate(arg_count));
2326 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2327
2328 Handle<Code> construct_builtin =
2329 isolate()->builtins()->JSConstructCall();
2330 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2331 context()->Plug(eax);
2332 } 2358 }
2333 2359
2334 2360
2335 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2361 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2336 ZoneList<Expression*>* args = expr->arguments(); 2362 ZoneList<Expression*>* args = expr->arguments();
2337 ASSERT(args->length() == 1); 2363 ASSERT(args->length() == 1);
2338 2364
2339 VisitForAccumulatorValue(args->at(0)); 2365 VisitForAccumulatorValue(args->at(0));
2340 2366
2341 Label materialize_true, materialize_false; 2367 Label materialize_true, materialize_false;
(...skipping 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after
4380 *context_length = 0; 4406 *context_length = 0;
4381 return previous_; 4407 return previous_;
4382 } 4408 }
4383 4409
4384 4410
4385 #undef __ 4411 #undef __
4386 4412
4387 } } // namespace v8::internal 4413 } } // namespace v8::internal
4388 4414
4389 #endif // V8_TARGET_ARCH_IA32 4415 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698