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

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

Issue 4469002: Improve positions recording for calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 10 years, 1 month 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
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 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 context()->Plug(eax); 1989 context()->Plug(eax);
1990 } 1990 }
1991 1991
1992 1992
1993 void FullCodeGenerator::EmitCallWithIC(Call* expr, 1993 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1994 Handle<Object> name, 1994 Handle<Object> name,
1995 RelocInfo::Mode mode) { 1995 RelocInfo::Mode mode) {
1996 // Code common for calls using the IC. 1996 // Code common for calls using the IC.
1997 ZoneList<Expression*>* args = expr->arguments(); 1997 ZoneList<Expression*>* args = expr->arguments();
1998 int arg_count = args->length(); 1998 int arg_count = args->length();
1999 for (int i = 0; i < arg_count; i++) { 1999 { PreserveStatementPositionScope scope(masm()->positions_recorder());
2000 VisitForStackValue(args->at(i)); 2000 for (int i = 0; i < arg_count; i++) {
2001 VisitForStackValue(args->at(i));
2002 }
2003 __ Set(ecx, Immediate(name));
2001 } 2004 }
2002 __ Set(ecx, Immediate(name));
2003 // Record source position of the IC call. 2005 // Record source position of the IC call.
2004 SetSourcePosition(expr->position()); 2006 SetSourcePosition(expr->position(), FORCED_POSITION);
2005 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2007 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2006 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); 2008 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
2007 EmitCallIC(ic, mode); 2009 EmitCallIC(ic, mode);
2008 // Restore context register. 2010 // Restore context register.
2009 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2011 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2010 context()->Plug(eax); 2012 context()->Plug(eax);
2011 } 2013 }
2012 2014
2013 2015
2014 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2016 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2015 Expression* key, 2017 Expression* key,
2016 RelocInfo::Mode mode) { 2018 RelocInfo::Mode mode) {
2017 // Code common for calls using the IC. 2019 // Code common for calls using the IC.
2018 ZoneList<Expression*>* args = expr->arguments(); 2020 ZoneList<Expression*>* args = expr->arguments();
2019 int arg_count = args->length(); 2021 int arg_count = args->length();
2020 for (int i = 0; i < arg_count; i++) { 2022 { PreserveStatementPositionScope scope(masm()->positions_recorder());
2021 VisitForStackValue(args->at(i)); 2023 for (int i = 0; i < arg_count; i++) {
2024 VisitForStackValue(args->at(i));
2025 }
2026 VisitForAccumulatorValue(key);
2027 __ mov(ecx, eax);
2022 } 2028 }
2023 VisitForAccumulatorValue(key);
2024 __ mov(ecx, eax);
2025 // Record source position of the IC call. 2029 // Record source position of the IC call.
2026 SetSourcePosition(expr->position()); 2030 SetSourcePosition(expr->position(), FORCED_POSITION);
2027 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2031 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2028 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize( 2032 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(
2029 arg_count, in_loop); 2033 arg_count, in_loop);
2030 EmitCallIC(ic, mode); 2034 EmitCallIC(ic, mode);
2031 // Restore context register. 2035 // Restore context register.
2032 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2036 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2033 context()->Plug(eax); 2037 context()->Plug(eax);
2034 } 2038 }
2035 2039
2036 2040
2037 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2041 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2038 // Code common for calls using the call stub. 2042 // Code common for calls using the call stub.
2039 ZoneList<Expression*>* args = expr->arguments(); 2043 ZoneList<Expression*>* args = expr->arguments();
2040 int arg_count = args->length(); 2044 int arg_count = args->length();
2041 for (int i = 0; i < arg_count; i++) { 2045 { PreserveStatementPositionScope scope(masm()->positions_recorder());
2042 VisitForStackValue(args->at(i)); 2046 for (int i = 0; i < arg_count; i++) {
2047 VisitForStackValue(args->at(i));
2048 }
2043 } 2049 }
2044 // Record source position for debugger. 2050 // Record source position for debugger.
2045 SetSourcePosition(expr->position()); 2051 SetSourcePosition(expr->position(), FORCED_POSITION);
2046 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2052 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2047 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 2053 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
2048 __ CallStub(&stub); 2054 __ CallStub(&stub);
2049 // Restore context register. 2055 // Restore context register.
2050 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2056 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2051 context()->DropAndPlug(1, eax); 2057 context()->DropAndPlug(1, eax);
2052 } 2058 }
2053 2059
2054 2060
2055 void FullCodeGenerator::VisitCall(Call* expr) { 2061 void FullCodeGenerator::VisitCall(Call* expr) {
2056 Comment cmnt(masm_, "[ Call"); 2062 Comment cmnt(masm_, "[ Call");
2057 Expression* fun = expr->expression(); 2063 Expression* fun = expr->expression();
2058 Variable* var = fun->AsVariableProxy()->AsVariable(); 2064 Variable* var = fun->AsVariableProxy()->AsVariable();
2059 2065
2060 if (var != NULL && var->is_possibly_eval()) { 2066 if (var != NULL && var->is_possibly_eval()) {
2061 // In a call to eval, we first call %ResolvePossiblyDirectEval to 2067 // In a call to eval, we first call %ResolvePossiblyDirectEval to
2062 // resolve the function we need to call and the receiver of the 2068 // resolve the function we need to call and the receiver of the
2063 // call. Then we call the resolved function using the given 2069 // call. Then we call the resolved function using the given
2064 // arguments. 2070 // arguments.
2065 VisitForStackValue(fun);
2066 __ push(Immediate(Factory::undefined_value())); // Reserved receiver slot.
2067
2068 // Push the arguments.
2069 ZoneList<Expression*>* args = expr->arguments(); 2071 ZoneList<Expression*>* args = expr->arguments();
2070 int arg_count = args->length(); 2072 int arg_count = args->length();
2071 for (int i = 0; i < arg_count; i++) { 2073 { PreserveStatementPositionScope pos_scope(masm()->positions_recorder());
2072 VisitForStackValue(args->at(i)); 2074 VisitForStackValue(fun);
2075 __ push(Immediate(Factory::undefined_value())); // Reserved receiver slot .
2076
2077 // Push the arguments.
2078 for (int i = 0; i < arg_count; i++) {
2079 VisitForStackValue(args->at(i));
2080 }
2081
2082 // Push copy of the function - found below the arguments.
2083 __ push(Operand(esp, (arg_count + 1) * kPointerSize));
2084
2085 // Push copy of the first argument or undefined if it doesn't exist.
2086 if (arg_count > 0) {
2087 __ push(Operand(esp, arg_count * kPointerSize));
2088 } else {
2089 __ push(Immediate(Factory::undefined_value()));
2090 }
2091
2092 // Push the receiver of the enclosing function and do runtime call.
2093 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
2094 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
2095
2096 // The runtime call returns a pair of values in eax (function) and
2097 // edx (receiver). Touch up the stack with the right values.
2098 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
2099 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2073 } 2100 }
2074
2075 // Push copy of the function - found below the arguments.
2076 __ push(Operand(esp, (arg_count + 1) * kPointerSize));
2077
2078 // Push copy of the first argument or undefined if it doesn't exist.
2079 if (arg_count > 0) {
2080 __ push(Operand(esp, arg_count * kPointerSize));
2081 } else {
2082 __ push(Immediate(Factory::undefined_value()));
2083 }
2084
2085 // Push the receiver of the enclosing function and do runtime call.
2086 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
2087 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
2088
2089 // The runtime call returns a pair of values in eax (function) and
2090 // edx (receiver). Touch up the stack with the right values.
2091 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
2092 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2093
2094 // Record source position for debugger. 2101 // Record source position for debugger.
2095 SetSourcePosition(expr->position()); 2102 SetSourcePosition(expr->position(), FORCED_POSITION);
2096 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2103 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2097 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 2104 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
2098 __ CallStub(&stub); 2105 __ CallStub(&stub);
2099 // Restore context register. 2106 // Restore context register.
2100 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2107 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2101 context()->DropAndPlug(1, eax); 2108 context()->DropAndPlug(1, eax);
2102 } else if (var != NULL && !var->is_this() && var->is_global()) { 2109 } else if (var != NULL && !var->is_this() && var->is_global()) {
2103 // Push global object as receiver for the call IC. 2110 // Push global object as receiver for the call IC.
2104 __ push(CodeGenerator::GlobalObject()); 2111 __ push(CodeGenerator::GlobalObject());
2105 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 2112 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
2106 } else if (var != NULL && var->AsSlot() != NULL && 2113 } else if (var != NULL && var->AsSlot() != NULL &&
2107 var->AsSlot()->type() == Slot::LOOKUP) { 2114 var->AsSlot()->type() == Slot::LOOKUP) {
2108 // Call to a lookup slot (dynamically introduced variable). 2115 // Call to a lookup slot (dynamically introduced variable).
2109 Label slow, done; 2116 Label slow, done;
2110 2117
2111 // Generate code for loading from variables potentially shadowed 2118 { PreserveStatementPositionScope scope(masm()->positions_recorder());
2112 // by eval-introduced variables. 2119 // Generate code for loading from variables potentially shadowed
2113 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), 2120 // by eval-introduced variables.
2114 NOT_INSIDE_TYPEOF, 2121 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
2115 &slow, 2122 NOT_INSIDE_TYPEOF,
2116 &done); 2123 &slow,
2124 &done);
2125 }
2117 2126
2118 __ bind(&slow); 2127 __ bind(&slow);
2119 // Call the runtime to find the function to call (returned in eax) 2128 // Call the runtime to find the function to call (returned in eax)
2120 // and the object holding it (returned in edx). 2129 // and the object holding it (returned in edx).
2121 __ push(context_register()); 2130 __ push(context_register());
2122 __ push(Immediate(var->name())); 2131 __ push(Immediate(var->name()));
2123 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2132 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2124 __ push(eax); // Function. 2133 __ push(eax); // Function.
2125 __ push(edx); // Receiver. 2134 __ push(edx); // Receiver.
2126 2135
(...skipping 18 matching lines...) Expand all
2145 Property* prop = fun->AsProperty(); 2154 Property* prop = fun->AsProperty();
2146 Literal* key = prop->key()->AsLiteral(); 2155 Literal* key = prop->key()->AsLiteral();
2147 if (key != NULL && key->handle()->IsSymbol()) { 2156 if (key != NULL && key->handle()->IsSymbol()) {
2148 // Call to a named property, use call IC. 2157 // Call to a named property, use call IC.
2149 VisitForStackValue(prop->obj()); 2158 VisitForStackValue(prop->obj());
2150 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2159 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2151 } else { 2160 } else {
2152 // Call to a keyed property. 2161 // Call to a keyed property.
2153 // For a synthetic property use keyed load IC followed by function call, 2162 // For a synthetic property use keyed load IC followed by function call,
2154 // for a regular property use keyed EmitCallIC. 2163 // for a regular property use keyed EmitCallIC.
2155 VisitForStackValue(prop->obj()); 2164 { PreserveStatementPositionScope scope(masm()->positions_recorder());
2165 VisitForStackValue(prop->obj());
2166 }
2156 if (prop->is_synthetic()) { 2167 if (prop->is_synthetic()) {
2157 VisitForAccumulatorValue(prop->key()); 2168 { PreserveStatementPositionScope scope(masm()->positions_recorder());
2169 VisitForAccumulatorValue(prop->key());
2170 }
2158 // Record source code position for IC call. 2171 // Record source code position for IC call.
2159 SetSourcePosition(prop->position()); 2172 SetSourcePosition(prop->position(), FORCED_POSITION);
2160 __ pop(edx); // We do not need to keep the receiver. 2173 __ pop(edx); // We do not need to keep the receiver.
2161 2174
2162 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 2175 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
2163 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2176 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2164 // Push result (function). 2177 // Push result (function).
2165 __ push(eax); 2178 __ push(eax);
2166 // Push Global receiver. 2179 // Push Global receiver.
2167 __ mov(ecx, CodeGenerator::GlobalObject()); 2180 __ mov(ecx, CodeGenerator::GlobalObject());
2168 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2181 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2169 EmitCallWithStub(expr); 2182 EmitCallWithStub(expr);
2170 } else { 2183 } else {
2171 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2184 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2172 } 2185 }
2173 } 2186 }
2174 } else { 2187 } else {
2175 // Call to some other expression. If the expression is an anonymous 2188 // Call to some other expression. If the expression is an anonymous
2176 // function literal not called in a loop, mark it as one that should 2189 // function literal not called in a loop, mark it as one that should
2177 // also use the full code generator. 2190 // also use the full code generator.
2178 FunctionLiteral* lit = fun->AsFunctionLiteral(); 2191 FunctionLiteral* lit = fun->AsFunctionLiteral();
2179 if (lit != NULL && 2192 if (lit != NULL &&
2180 lit->name()->Equals(Heap::empty_string()) && 2193 lit->name()->Equals(Heap::empty_string()) &&
2181 loop_depth() == 0) { 2194 loop_depth() == 0) {
2182 lit->set_try_full_codegen(true); 2195 lit->set_try_full_codegen(true);
2183 } 2196 }
2184 VisitForStackValue(fun); 2197 { PreserveStatementPositionScope scope(masm()->positions_recorder());
2198 VisitForStackValue(fun);
2199 }
2185 // Load global receiver object. 2200 // Load global receiver object.
2186 __ mov(ebx, CodeGenerator::GlobalObject()); 2201 __ mov(ebx, CodeGenerator::GlobalObject());
2187 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2202 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2188 // Emit function call. 2203 // Emit function call.
2189 EmitCallWithStub(expr); 2204 EmitCallWithStub(expr);
2190 } 2205 }
2191 } 2206 }
2192 2207
2193 2208
2194 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2209 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
(...skipping 1539 matching lines...) Expand 10 before | Expand all | Expand 10 after
3734 // And return. 3749 // And return.
3735 __ ret(0); 3750 __ ret(0);
3736 } 3751 }
3737 3752
3738 3753
3739 #undef __ 3754 #undef __
3740 3755
3741 } } // namespace v8::internal 3756 } } // namespace v8::internal
3742 3757
3743 #endif // V8_TARGET_ARCH_IA32 3758 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/assembler.h ('K') | « src/ia32/codegen-ia32.cc ('k') | src/jump-target-heavy.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698