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

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

Issue 2514393002: [fullcodegen] Remove deprecated support for lookup variables, eval and with. (Closed)
Patch Set: Address comment Created 4 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/s390/full-codegen-s390.cc ('k') | src/full-codegen/x87/full-codegen-x87.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/full-codegen/full-codegen.h" 7 #include "src/full-codegen/full-codegen.h"
8 #include "src/ast/compile-time-value.h" 8 #include "src/ast/compile-time-value.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 if (variable->binding_needs_init()) { 763 if (variable->binding_needs_init()) {
764 Comment cmnt(masm_, "[ VariableDeclaration"); 764 Comment cmnt(masm_, "[ VariableDeclaration");
765 EmitDebugCheckDeclarationContext(variable); 765 EmitDebugCheckDeclarationContext(variable);
766 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 766 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
767 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister); 767 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister);
768 // No write barrier since the hole value is in old space. 768 // No write barrier since the hole value is in old space.
769 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 769 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
770 } 770 }
771 break; 771 break;
772 772
773 case VariableLocation::LOOKUP: { 773 case VariableLocation::LOOKUP:
774 Comment cmnt(masm_, "[ VariableDeclaration");
775 DCHECK_EQ(VAR, variable->mode());
776 DCHECK(!variable->binding_needs_init());
777 __ Push(variable->name());
778 __ CallRuntime(Runtime::kDeclareEvalVar);
779 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
780 break;
781 }
782
783 case VariableLocation::MODULE: 774 case VariableLocation::MODULE:
784 UNREACHABLE(); 775 UNREACHABLE();
785 } 776 }
786 } 777 }
787 778
788 779
789 void FullCodeGenerator::VisitFunctionDeclaration( 780 void FullCodeGenerator::VisitFunctionDeclaration(
790 FunctionDeclaration* declaration) { 781 FunctionDeclaration* declaration) {
791 VariableProxy* proxy = declaration->proxy(); 782 VariableProxy* proxy = declaration->proxy();
792 Variable* variable = proxy->var(); 783 Variable* variable = proxy->var();
(...skipping 30 matching lines...) Expand all
823 offset, 814 offset,
824 result_register(), 815 result_register(),
825 rcx, 816 rcx,
826 kDontSaveFPRegs, 817 kDontSaveFPRegs,
827 EMIT_REMEMBERED_SET, 818 EMIT_REMEMBERED_SET,
828 OMIT_SMI_CHECK); 819 OMIT_SMI_CHECK);
829 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 820 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
830 break; 821 break;
831 } 822 }
832 823
833 case VariableLocation::LOOKUP: { 824 case VariableLocation::LOOKUP:
834 Comment cmnt(masm_, "[ FunctionDeclaration");
835 PushOperand(variable->name());
836 VisitForStackValue(declaration->fun());
837 CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
838 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
839 break;
840 }
841
842 case VariableLocation::MODULE: 825 case VariableLocation::MODULE:
843 UNREACHABLE(); 826 UNREACHABLE();
844 } 827 }
845 } 828 }
846 829
847 830
848 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 831 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
849 // Call the runtime to declare the globals. 832 // Call the runtime to declare the globals.
850 __ Push(pairs); 833 __ Push(pairs);
851 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 834 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, 1114 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
1132 int offset, 1115 int offset,
1133 FeedbackVectorSlot slot) { 1116 FeedbackVectorSlot slot) {
1134 DCHECK(NeedsHomeObject(initializer)); 1117 DCHECK(NeedsHomeObject(initializer));
1135 __ movp(StoreDescriptor::ReceiverRegister(), rax); 1118 __ movp(StoreDescriptor::ReceiverRegister(), rax);
1136 __ movp(StoreDescriptor::ValueRegister(), 1119 __ movp(StoreDescriptor::ValueRegister(),
1137 Operand(rsp, offset * kPointerSize)); 1120 Operand(rsp, offset * kPointerSize));
1138 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1121 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1139 } 1122 }
1140 1123
1141
1142 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1143 TypeofMode typeof_mode,
1144 Label* slow) {
1145 Register context = rsi;
1146 Register temp = rdx;
1147
1148 int to_check = scope()->ContextChainLengthUntilOutermostSloppyEval();
1149 for (Scope* s = scope(); to_check > 0; s = s->outer_scope()) {
1150 if (!s->NeedsContext()) continue;
1151 if (s->calls_sloppy_eval()) {
1152 // Check that extension is "the hole".
1153 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1154 Heap::kTheHoleValueRootIndex, slow);
1155 }
1156 // Load next context in chain.
1157 __ movp(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
1158 // Walk the rest of the chain without clobbering rsi.
1159 context = temp;
1160 to_check--;
1161 }
1162
1163 // All extension objects were empty and it is safe to use a normal global
1164 // load machinery.
1165 EmitGlobalVariableLoad(proxy, typeof_mode);
1166 }
1167
1168
1169 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1170 Label* slow) {
1171 DCHECK(var->IsContextSlot());
1172 Register context = rsi;
1173 Register temp = rbx;
1174
1175 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1176 if (s->NeedsContext()) {
1177 if (s->calls_sloppy_eval()) {
1178 // Check that extension is "the hole".
1179 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1180 Heap::kTheHoleValueRootIndex, slow);
1181 }
1182 __ movp(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
1183 // Walk the rest of the chain without clobbering rsi.
1184 context = temp;
1185 }
1186 }
1187 // Check that last extension is "the hole".
1188 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1189 Heap::kTheHoleValueRootIndex, slow);
1190
1191 // This function is used only for loads, not stores, so it's safe to
1192 // return an rsi-based operand (the write barrier cannot be allowed to
1193 // destroy the rsi register).
1194 return ContextOperand(context, var->index());
1195 }
1196
1197
1198 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1199 TypeofMode typeof_mode,
1200 Label* slow, Label* done) {
1201 // Generate fast-case code for variables that might be shadowed by
1202 // eval-introduced variables. Eval is used a lot without
1203 // introducing variables. In those cases, we do not want to
1204 // perform a runtime call for all variables in the scope
1205 // containing the eval.
1206 Variable* var = proxy->var();
1207 if (var->mode() == DYNAMIC_GLOBAL) {
1208 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1209 __ jmp(done);
1210 } else if (var->mode() == DYNAMIC_LOCAL) {
1211 Variable* local = var->local_if_not_shadowed();
1212 __ movp(rax, ContextSlotOperandCheckExtensions(local, slow));
1213 if (local->binding_needs_init()) {
1214 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1215 __ j(not_equal, done);
1216 __ Push(var->name());
1217 __ CallRuntime(Runtime::kThrowReferenceError);
1218 } else {
1219 __ jmp(done);
1220 }
1221 }
1222 }
1223
1224 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1124 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1225 TypeofMode typeof_mode) { 1125 TypeofMode typeof_mode) {
1226 // Record position before possible IC call. 1126 // Record position before possible IC call.
1227 SetExpressionPosition(proxy); 1127 SetExpressionPosition(proxy);
1228 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1128 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1229 Variable* var = proxy->var(); 1129 Variable* var = proxy->var();
1230 1130
1231 // Three cases: global variables, lookup variables, and all other types of 1131 // Two cases: global variable, and all other types of variables.
1232 // variables.
1233 switch (var->location()) { 1132 switch (var->location()) {
1234 case VariableLocation::UNALLOCATED: { 1133 case VariableLocation::UNALLOCATED: {
1235 Comment cmnt(masm_, "[ Global variable"); 1134 Comment cmnt(masm_, "[ Global variable");
1236 EmitGlobalVariableLoad(proxy, typeof_mode); 1135 EmitGlobalVariableLoad(proxy, typeof_mode);
1237 context()->Plug(rax); 1136 context()->Plug(rax);
1238 break; 1137 break;
1239 } 1138 }
1240 1139
1241 case VariableLocation::PARAMETER: 1140 case VariableLocation::PARAMETER:
1242 case VariableLocation::LOCAL: 1141 case VariableLocation::LOCAL:
(...skipping 12 matching lines...) Expand all
1255 __ Push(var->name()); 1154 __ Push(var->name());
1256 __ CallRuntime(Runtime::kThrowReferenceError); 1155 __ CallRuntime(Runtime::kThrowReferenceError);
1257 __ bind(&done); 1156 __ bind(&done);
1258 context()->Plug(rax); 1157 context()->Plug(rax);
1259 break; 1158 break;
1260 } 1159 }
1261 context()->Plug(var); 1160 context()->Plug(var);
1262 break; 1161 break;
1263 } 1162 }
1264 1163
1265 case VariableLocation::LOOKUP: { 1164 case VariableLocation::LOOKUP:
1266 Comment cmnt(masm_, "[ Lookup slot");
1267 Label done, slow;
1268 // Generate code for loading from variables potentially shadowed
1269 // by eval-introduced variables.
1270 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1271 __ bind(&slow);
1272 __ Push(var->name());
1273 Runtime::FunctionId function_id =
1274 typeof_mode == NOT_INSIDE_TYPEOF
1275 ? Runtime::kLoadLookupSlot
1276 : Runtime::kLoadLookupSlotInsideTypeof;
1277 __ CallRuntime(function_id);
1278 __ bind(&done);
1279 context()->Plug(rax);
1280 break;
1281 }
1282
1283 case VariableLocation::MODULE: 1165 case VariableLocation::MODULE:
1284 UNREACHABLE(); 1166 UNREACHABLE();
1285 } 1167 }
1286 } 1168 }
1287 1169
1288 1170
1289 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1171 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1290 Expression* expression = (property == NULL) ? NULL : property->value(); 1172 Expression* expression = (property == NULL) ? NULL : property->value();
1291 if (expression == NULL) { 1173 if (expression == NULL) {
1292 OperandStackDepthIncrement(1); 1174 OperandStackDepthIncrement(1);
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 __ movp(rdx, location); 1871 __ movp(rdx, location);
1990 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1872 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1991 __ j(equal, &uninitialized_this); 1873 __ j(equal, &uninitialized_this);
1992 __ Push(var->name()); 1874 __ Push(var->name());
1993 __ CallRuntime(Runtime::kThrowReferenceError); 1875 __ CallRuntime(Runtime::kThrowReferenceError);
1994 __ bind(&uninitialized_this); 1876 __ bind(&uninitialized_this);
1995 EmitStoreToStackLocalOrContextSlot(var, location); 1877 EmitStoreToStackLocalOrContextSlot(var, location);
1996 1878
1997 } else { 1879 } else {
1998 DCHECK(var->mode() != CONST || op == Token::INIT); 1880 DCHECK(var->mode() != CONST || op == Token::INIT);
1999 if (var->IsLookupSlot()) { 1881 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2000 // Assignment to var. 1882 DCHECK(!var->IsLookupSlot());
2001 __ Push(var->name()); 1883 // Assignment to var or initializing assignment to let/const in harmony
2002 __ Push(rax); 1884 // mode.
2003 __ CallRuntime(is_strict(language_mode()) 1885 MemOperand location = VarOperand(var, rcx);
2004 ? Runtime::kStoreLookupSlot_Strict 1886 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2005 : Runtime::kStoreLookupSlot_Sloppy); 1887 // Check for an uninitialized let binding.
2006 } else { 1888 __ movp(rdx, location);
2007 // Assignment to var or initializing assignment to let/const in harmony 1889 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
2008 // mode. 1890 __ Check(equal, kLetBindingReInitialization);
2009 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2010 MemOperand location = VarOperand(var, rcx);
2011 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2012 // Check for an uninitialized let binding.
2013 __ movp(rdx, location);
2014 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
2015 __ Check(equal, kLetBindingReInitialization);
2016 }
2017 EmitStoreToStackLocalOrContextSlot(var, location);
2018 } 1891 }
1892 EmitStoreToStackLocalOrContextSlot(var, location);
2019 } 1893 }
2020 } 1894 }
2021 1895
2022 1896
2023 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1897 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2024 // Assignment to a property, using a named store IC. 1898 // Assignment to a property, using a named store IC.
2025 Property* prop = expr->target()->AsProperty(); 1899 Property* prop = expr->target()->AsProperty();
2026 DCHECK(prop != NULL); 1900 DCHECK(prop != NULL);
2027 DCHECK(prop->key()->IsLiteral()); 1901 DCHECK(prop->key()->IsLiteral());
2028 1902
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2228 __ Set(rax, arg_count); 2102 __ Set(rax, arg_count);
2229 CallIC(code); 2103 CallIC(code);
2230 OperandStackDepthDecrement(arg_count + 1); 2104 OperandStackDepthDecrement(arg_count + 1);
2231 2105
2232 RecordJSReturnSite(expr); 2106 RecordJSReturnSite(expr);
2233 RestoreContext(); 2107 RestoreContext();
2234 // Discard the function left on TOS. 2108 // Discard the function left on TOS.
2235 context()->DropAndPlug(1, rax); 2109 context()->DropAndPlug(1, rax);
2236 } 2110 }
2237 2111
2238 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2239 int arg_count = expr->arguments()->length();
2240 // Push copy of the first argument or undefined if it doesn't exist.
2241 if (arg_count > 0) {
2242 __ Push(Operand(rsp, arg_count * kPointerSize));
2243 } else {
2244 __ PushRoot(Heap::kUndefinedValueRootIndex);
2245 }
2246
2247 // Push the enclosing function.
2248 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
2249
2250 // Push the language mode.
2251 __ Push(Smi::FromInt(language_mode()));
2252
2253 // Push the start position of the scope the calls resides in.
2254 __ Push(Smi::FromInt(scope()->start_position()));
2255
2256 // Push the source position of the eval call.
2257 __ Push(Smi::FromInt(expr->position()));
2258
2259 // Do the runtime call.
2260 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2261 }
2262
2263
2264 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2265 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2266 VariableProxy* callee = expr->expression()->AsVariableProxy();
2267 if (callee->var()->IsLookupSlot()) {
2268 Label slow, done;
2269 SetExpressionPosition(callee);
2270 // Generate code for loading from variables potentially shadowed by
2271 // eval-introduced variables.
2272 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2273 __ bind(&slow);
2274 // Call the runtime to find the function to call (returned in rax) and
2275 // the object holding it (returned in rdx).
2276 __ Push(callee->name());
2277 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2278 PushOperand(rax); // Function.
2279 PushOperand(rdx); // Receiver.
2280 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2281
2282 // If fast case code has been generated, emit code to push the function
2283 // and receiver and have the slow path jump around this code.
2284 if (done.is_linked()) {
2285 Label call;
2286 __ jmp(&call, Label::kNear);
2287 __ bind(&done);
2288 // Push function.
2289 __ Push(rax);
2290 // Pass undefined as the receiver, which is the WithBaseObject of a
2291 // non-object environment record. If the callee is sloppy, it will patch
2292 // it up to be the global receiver.
2293 __ PushRoot(Heap::kUndefinedValueRootIndex);
2294 __ bind(&call);
2295 }
2296 } else {
2297 VisitForStackValue(callee);
2298 // refEnv.WithBaseObject()
2299 OperandStackDepthIncrement(1);
2300 __ PushRoot(Heap::kUndefinedValueRootIndex);
2301 }
2302 }
2303
2304
2305 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2306 // In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
2307 // to resolve the function we need to call. Then we call the resolved
2308 // function using the given arguments.
2309 ZoneList<Expression*>* args = expr->arguments();
2310 int arg_count = args->length();
2311 PushCalleeAndWithBaseObject(expr);
2312
2313 // Push the arguments.
2314 for (int i = 0; i < arg_count; i++) {
2315 VisitForStackValue(args->at(i));
2316 }
2317
2318 // Push a copy of the function (found below the arguments) and resolve
2319 // eval.
2320 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize));
2321 EmitResolvePossiblyDirectEval(expr);
2322
2323 // Touch up the callee.
2324 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
2325
2326 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2327
2328 SetCallPosition(expr);
2329 Handle<Code> code = CodeFactory::CallIC(isolate(), ConvertReceiverMode::kAny,
2330 expr->tail_call_mode())
2331 .code();
2332 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot()));
2333 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
2334 __ Set(rax, arg_count);
2335 __ call(code, RelocInfo::CODE_TARGET);
2336 OperandStackDepthDecrement(arg_count + 1);
2337 RecordJSReturnSite(expr);
2338 RestoreContext();
2339 context()->DropAndPlug(1, rax);
2340 }
2341
2342
2343 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2112 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2344 Comment cmnt(masm_, "[ CallNew"); 2113 Comment cmnt(masm_, "[ CallNew");
2345 // According to ECMA-262, section 11.2.2, page 44, the function 2114 // According to ECMA-262, section 11.2.2, page 44, the function
2346 // expression in new calls must be evaluated before the 2115 // expression in new calls must be evaluated before the
2347 // arguments. 2116 // arguments.
2348 2117
2349 // Push constructor on the stack. If it's not a function it's used as 2118 // Push constructor on the stack. If it's not a function it's used as
2350 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2119 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2351 // ignored. 2120 // ignored.
2352 DCHECK(!expr->expression()->IsSuperPropertyReference()); 2121 DCHECK(!expr->expression()->IsSuperPropertyReference());
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
2757 // Delete of an unqualified identifier is disallowed in strict mode but 2526 // Delete of an unqualified identifier is disallowed in strict mode but
2758 // "delete this" is allowed. 2527 // "delete this" is allowed.
2759 bool is_this = var->is_this(); 2528 bool is_this = var->is_this();
2760 DCHECK(is_sloppy(language_mode()) || is_this); 2529 DCHECK(is_sloppy(language_mode()) || is_this);
2761 if (var->IsUnallocated()) { 2530 if (var->IsUnallocated()) {
2762 __ movp(rax, NativeContextOperand()); 2531 __ movp(rax, NativeContextOperand());
2763 __ Push(ContextOperand(rax, Context::EXTENSION_INDEX)); 2532 __ Push(ContextOperand(rax, Context::EXTENSION_INDEX));
2764 __ Push(var->name()); 2533 __ Push(var->name());
2765 __ CallRuntime(Runtime::kDeleteProperty_Sloppy); 2534 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
2766 context()->Plug(rax); 2535 context()->Plug(rax);
2767 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 2536 } else {
2537 DCHECK(!var->IsLookupSlot());
2538 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2768 // Result of deleting non-global variables is false. 'this' is 2539 // Result of deleting non-global variables is false. 'this' is
2769 // not really a variable, though we implement it as one. The 2540 // not really a variable, though we implement it as one. The
2770 // subexpression does not have side effects. 2541 // subexpression does not have side effects.
2771 context()->Plug(is_this); 2542 context()->Plug(is_this);
2772 } else {
2773 // Non-global variable. Call the runtime to try to delete from the
2774 // context where the variable was introduced.
2775 __ Push(var->name());
2776 __ CallRuntime(Runtime::kDeleteLookupSlot);
2777 context()->Plug(rax);
2778 } 2543 }
2779 } else { 2544 } else {
2780 // Result of deleting non-property, non-variable reference is true. 2545 // Result of deleting non-property, non-variable reference is true.
2781 // The subexpression may have side effects. 2546 // The subexpression may have side effects.
2782 VisitForEffect(expr->expression()); 2547 VisitForEffect(expr->expression());
2783 context()->Plug(true); 2548 context()->Plug(true);
2784 } 2549 }
2785 break; 2550 break;
2786 } 2551 }
2787 2552
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
3464 DCHECK_EQ( 3229 DCHECK_EQ(
3465 isolate->builtins()->OnStackReplacement()->entry(), 3230 isolate->builtins()->OnStackReplacement()->entry(),
3466 Assembler::target_address_at(call_target_address, unoptimized_code)); 3231 Assembler::target_address_at(call_target_address, unoptimized_code));
3467 return ON_STACK_REPLACEMENT; 3232 return ON_STACK_REPLACEMENT;
3468 } 3233 }
3469 3234
3470 } // namespace internal 3235 } // namespace internal
3471 } // namespace v8 3236 } // namespace v8
3472 3237
3473 #endif // V8_TARGET_ARCH_X64 3238 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/full-codegen/s390/full-codegen-s390.cc ('k') | src/full-codegen/x87/full-codegen-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698