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

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

Issue 5277008: Save full source position state to avoid forced positions. (Closed)
Patch Set: Created 10 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
« no previous file with comments | « src/full-codegen.cc ('k') | src/x64/full-codegen-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 1985 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 context()->Plug(eax); 1996 context()->Plug(eax);
1997 } 1997 }
1998 1998
1999 1999
2000 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2000 void FullCodeGenerator::EmitCallWithIC(Call* expr,
2001 Handle<Object> name, 2001 Handle<Object> name,
2002 RelocInfo::Mode mode) { 2002 RelocInfo::Mode mode) {
2003 // Code common for calls using the IC. 2003 // Code common for calls using the IC.
2004 ZoneList<Expression*>* args = expr->arguments(); 2004 ZoneList<Expression*>* args = expr->arguments();
2005 int arg_count = args->length(); 2005 int arg_count = args->length();
2006 { PreserveStatementPositionScope scope(masm()->positions_recorder()); 2006 { PreservePositionScope scope(masm()->positions_recorder());
2007 for (int i = 0; i < arg_count; i++) { 2007 for (int i = 0; i < arg_count; i++) {
2008 VisitForStackValue(args->at(i)); 2008 VisitForStackValue(args->at(i));
2009 } 2009 }
2010 __ Set(ecx, Immediate(name)); 2010 __ Set(ecx, Immediate(name));
2011 } 2011 }
2012 // Record source position of the IC call. 2012 // Record source position of the IC call.
2013 SetSourcePosition(expr->position(), FORCED_POSITION); 2013 SetSourcePosition(expr->position());
2014 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2014 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2015 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); 2015 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop);
2016 EmitCallIC(ic, mode); 2016 EmitCallIC(ic, mode);
2017 // Restore context register. 2017 // Restore context register.
2018 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2018 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2019 context()->Plug(eax); 2019 context()->Plug(eax);
2020 } 2020 }
2021 2021
2022 2022
2023 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2023 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2024 Expression* key, 2024 Expression* key,
2025 RelocInfo::Mode mode) { 2025 RelocInfo::Mode mode) {
2026 // Load the key. 2026 // Load the key.
2027 VisitForAccumulatorValue(key); 2027 VisitForAccumulatorValue(key);
2028 2028
2029 // Swap the name of the function and the receiver on the stack to follow 2029 // Swap the name of the function and the receiver on the stack to follow
2030 // the calling convention for call ICs. 2030 // the calling convention for call ICs.
2031 __ pop(ecx); 2031 __ pop(ecx);
2032 __ push(eax); 2032 __ push(eax);
2033 __ push(ecx); 2033 __ push(ecx);
2034 2034
2035 // Load the arguments. 2035 // Load the arguments.
2036 ZoneList<Expression*>* args = expr->arguments(); 2036 ZoneList<Expression*>* args = expr->arguments();
2037 int arg_count = args->length(); 2037 int arg_count = args->length();
2038 { PreserveStatementPositionScope scope(masm()->positions_recorder()); 2038 { PreservePositionScope scope(masm()->positions_recorder());
2039 for (int i = 0; i < arg_count; i++) { 2039 for (int i = 0; i < arg_count; i++) {
2040 VisitForStackValue(args->at(i)); 2040 VisitForStackValue(args->at(i));
2041 } 2041 }
2042 } 2042 }
2043 // Record source position of the IC call. 2043 // Record source position of the IC call.
2044 SetSourcePosition(expr->position(), FORCED_POSITION); 2044 SetSourcePosition(expr->position());
2045 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2045 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2046 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); 2046 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop);
2047 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2047 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2048 EmitCallIC(ic, mode); 2048 EmitCallIC(ic, mode);
2049 // Restore context register. 2049 // Restore context register.
2050 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2050 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2051 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2051 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2052 } 2052 }
2053 2053
2054 2054
2055 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2055 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2056 // Code common for calls using the call stub. 2056 // Code common for calls using the call stub.
2057 ZoneList<Expression*>* args = expr->arguments(); 2057 ZoneList<Expression*>* args = expr->arguments();
2058 int arg_count = args->length(); 2058 int arg_count = args->length();
2059 { PreserveStatementPositionScope scope(masm()->positions_recorder()); 2059 { PreservePositionScope scope(masm()->positions_recorder());
2060 for (int i = 0; i < arg_count; i++) { 2060 for (int i = 0; i < arg_count; i++) {
2061 VisitForStackValue(args->at(i)); 2061 VisitForStackValue(args->at(i));
2062 } 2062 }
2063 } 2063 }
2064 // Record source position for debugger. 2064 // Record source position for debugger.
2065 SetSourcePosition(expr->position(), FORCED_POSITION); 2065 SetSourcePosition(expr->position());
2066 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2066 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2067 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 2067 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
2068 __ CallStub(&stub); 2068 __ CallStub(&stub);
2069 // Restore context register. 2069 // Restore context register.
2070 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2070 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2071 context()->DropAndPlug(1, eax); 2071 context()->DropAndPlug(1, eax);
2072 } 2072 }
2073 2073
2074 2074
2075 void FullCodeGenerator::VisitCall(Call* expr) { 2075 void FullCodeGenerator::VisitCall(Call* expr) {
2076 Comment cmnt(masm_, "[ Call"); 2076 Comment cmnt(masm_, "[ Call");
2077 Expression* fun = expr->expression(); 2077 Expression* fun = expr->expression();
2078 Variable* var = fun->AsVariableProxy()->AsVariable(); 2078 Variable* var = fun->AsVariableProxy()->AsVariable();
2079 2079
2080 if (var != NULL && var->is_possibly_eval()) { 2080 if (var != NULL && var->is_possibly_eval()) {
2081 // In a call to eval, we first call %ResolvePossiblyDirectEval to 2081 // In a call to eval, we first call %ResolvePossiblyDirectEval to
2082 // resolve the function we need to call and the receiver of the 2082 // resolve the function we need to call and the receiver of the
2083 // call. Then we call the resolved function using the given 2083 // call. Then we call the resolved function using the given
2084 // arguments. 2084 // arguments.
2085 ZoneList<Expression*>* args = expr->arguments(); 2085 ZoneList<Expression*>* args = expr->arguments();
2086 int arg_count = args->length(); 2086 int arg_count = args->length();
2087 { PreserveStatementPositionScope pos_scope(masm()->positions_recorder()); 2087 { PreservePositionScope pos_scope(masm()->positions_recorder());
2088 VisitForStackValue(fun); 2088 VisitForStackValue(fun);
2089 // Reserved receiver slot. 2089 // Reserved receiver slot.
2090 __ push(Immediate(Factory::undefined_value())); 2090 __ push(Immediate(Factory::undefined_value()));
2091 2091
2092 // Push the arguments. 2092 // Push the arguments.
2093 for (int i = 0; i < arg_count; i++) { 2093 for (int i = 0; i < arg_count; i++) {
2094 VisitForStackValue(args->at(i)); 2094 VisitForStackValue(args->at(i));
2095 } 2095 }
2096 2096
2097 // Push copy of the function - found below the arguments. 2097 // Push copy of the function - found below the arguments.
2098 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); 2098 __ push(Operand(esp, (arg_count + 1) * kPointerSize));
2099 2099
2100 // Push copy of the first argument or undefined if it doesn't exist. 2100 // Push copy of the first argument or undefined if it doesn't exist.
2101 if (arg_count > 0) { 2101 if (arg_count > 0) {
2102 __ push(Operand(esp, arg_count * kPointerSize)); 2102 __ push(Operand(esp, arg_count * kPointerSize));
2103 } else { 2103 } else {
2104 __ push(Immediate(Factory::undefined_value())); 2104 __ push(Immediate(Factory::undefined_value()));
2105 } 2105 }
2106 2106
2107 // Push the receiver of the enclosing function and do runtime call. 2107 // Push the receiver of the enclosing function and do runtime call.
2108 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize)); 2108 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
2109 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); 2109 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
2110 2110
2111 // The runtime call returns a pair of values in eax (function) and 2111 // The runtime call returns a pair of values in eax (function) and
2112 // edx (receiver). Touch up the stack with the right values. 2112 // edx (receiver). Touch up the stack with the right values.
2113 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); 2113 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
2114 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2114 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2115 } 2115 }
2116 // Record source position for debugger. 2116 // Record source position for debugger.
2117 SetSourcePosition(expr->position(), FORCED_POSITION); 2117 SetSourcePosition(expr->position());
2118 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2118 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2119 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 2119 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
2120 __ CallStub(&stub); 2120 __ CallStub(&stub);
2121 // Restore context register. 2121 // Restore context register.
2122 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2122 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2123 context()->DropAndPlug(1, eax); 2123 context()->DropAndPlug(1, eax);
2124 } else if (var != NULL && !var->is_this() && var->is_global()) { 2124 } else if (var != NULL && !var->is_this() && var->is_global()) {
2125 // Push global object as receiver for the call IC. 2125 // Push global object as receiver for the call IC.
2126 __ push(GlobalObjectOperand()); 2126 __ push(GlobalObjectOperand());
2127 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 2127 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
2128 } else if (var != NULL && var->AsSlot() != NULL && 2128 } else if (var != NULL && var->AsSlot() != NULL &&
2129 var->AsSlot()->type() == Slot::LOOKUP) { 2129 var->AsSlot()->type() == Slot::LOOKUP) {
2130 // Call to a lookup slot (dynamically introduced variable). 2130 // Call to a lookup slot (dynamically introduced variable).
2131 Label slow, done; 2131 Label slow, done;
2132 2132
2133 { PreserveStatementPositionScope scope(masm()->positions_recorder()); 2133 { PreservePositionScope scope(masm()->positions_recorder());
2134 // Generate code for loading from variables potentially shadowed 2134 // Generate code for loading from variables potentially shadowed
2135 // by eval-introduced variables. 2135 // by eval-introduced variables.
2136 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), 2136 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
2137 NOT_INSIDE_TYPEOF, 2137 NOT_INSIDE_TYPEOF,
2138 &slow, 2138 &slow,
2139 &done); 2139 &done);
2140 } 2140 }
2141 2141
2142 __ bind(&slow); 2142 __ bind(&slow);
2143 // Call the runtime to find the function to call (returned in eax) 2143 // Call the runtime to find the function to call (returned in eax)
(...skipping 25 matching lines...) Expand all
2169 Property* prop = fun->AsProperty(); 2169 Property* prop = fun->AsProperty();
2170 Literal* key = prop->key()->AsLiteral(); 2170 Literal* key = prop->key()->AsLiteral();
2171 if (key != NULL && key->handle()->IsSymbol()) { 2171 if (key != NULL && key->handle()->IsSymbol()) {
2172 // Call to a named property, use call IC. 2172 // Call to a named property, use call IC.
2173 VisitForStackValue(prop->obj()); 2173 VisitForStackValue(prop->obj());
2174 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2174 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2175 } else { 2175 } else {
2176 // Call to a keyed property. 2176 // Call to a keyed property.
2177 // For a synthetic property use keyed load IC followed by function call, 2177 // For a synthetic property use keyed load IC followed by function call,
2178 // for a regular property use keyed EmitCallIC. 2178 // for a regular property use keyed EmitCallIC.
2179 { PreserveStatementPositionScope scope(masm()->positions_recorder()); 2179 { PreservePositionScope scope(masm()->positions_recorder());
2180 VisitForStackValue(prop->obj()); 2180 VisitForStackValue(prop->obj());
2181 } 2181 }
2182 if (prop->is_synthetic()) { 2182 if (prop->is_synthetic()) {
2183 { PreserveStatementPositionScope scope(masm()->positions_recorder()); 2183 { PreservePositionScope scope(masm()->positions_recorder());
2184 VisitForAccumulatorValue(prop->key()); 2184 VisitForAccumulatorValue(prop->key());
2185 } 2185 }
2186 // Record source code position for IC call. 2186 // Record source code position for IC call.
2187 SetSourcePosition(prop->position(), FORCED_POSITION); 2187 SetSourcePosition(prop->position());
2188 __ pop(edx); // We do not need to keep the receiver. 2188 __ pop(edx); // We do not need to keep the receiver.
2189 2189
2190 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 2190 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
2191 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2191 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2192 // Push result (function). 2192 // Push result (function).
2193 __ push(eax); 2193 __ push(eax);
2194 // Push Global receiver. 2194 // Push Global receiver.
2195 __ mov(ecx, GlobalObjectOperand()); 2195 __ mov(ecx, GlobalObjectOperand());
2196 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2196 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2197 EmitCallWithStub(expr); 2197 EmitCallWithStub(expr);
2198 } else { 2198 } else {
2199 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2199 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2200 } 2200 }
2201 } 2201 }
2202 } else { 2202 } else {
2203 // Call to some other expression. If the expression is an anonymous 2203 // Call to some other expression. If the expression is an anonymous
2204 // function literal not called in a loop, mark it as one that should 2204 // function literal not called in a loop, mark it as one that should
2205 // also use the full code generator. 2205 // also use the full code generator.
2206 FunctionLiteral* lit = fun->AsFunctionLiteral(); 2206 FunctionLiteral* lit = fun->AsFunctionLiteral();
2207 if (lit != NULL && 2207 if (lit != NULL &&
2208 lit->name()->Equals(Heap::empty_string()) && 2208 lit->name()->Equals(Heap::empty_string()) &&
2209 loop_depth() == 0) { 2209 loop_depth() == 0) {
2210 lit->set_try_full_codegen(true); 2210 lit->set_try_full_codegen(true);
2211 } 2211 }
2212 { PreserveStatementPositionScope scope(masm()->positions_recorder()); 2212 { PreservePositionScope scope(masm()->positions_recorder());
2213 VisitForStackValue(fun); 2213 VisitForStackValue(fun);
2214 } 2214 }
2215 // Load global receiver object. 2215 // Load global receiver object.
2216 __ mov(ebx, GlobalObjectOperand()); 2216 __ mov(ebx, GlobalObjectOperand());
2217 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2217 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2218 // Emit function call. 2218 // Emit function call.
2219 EmitCallWithStub(expr); 2219 EmitCallWithStub(expr);
2220 } 2220 }
2221 } 2221 }
2222 2222
(...skipping 1725 matching lines...) Expand 10 before | Expand all | Expand 10 after
3948 // And return. 3948 // And return.
3949 __ ret(0); 3949 __ ret(0);
3950 } 3950 }
3951 3951
3952 3952
3953 #undef __ 3953 #undef __
3954 3954
3955 } } // namespace v8::internal 3955 } } // namespace v8::internal
3956 3956
3957 #endif // V8_TARGET_ARCH_IA32 3957 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698