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

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

Issue 1222203007: Use FullCodeGenerator::EmitGlobalVariableLoad() where possible to avoid code duplication. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebasing Created 5 years, 5 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
« no previous file with comments | « src/full-codegen.cc ('k') | src/mips/full-codegen-mips.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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 __ j(equal, &fast, Label::kNear); 1337 __ j(equal, &fast, Label::kNear);
1338 // Check that extension is NULL. 1338 // Check that extension is NULL.
1339 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1339 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
1340 __ j(not_equal, slow); 1340 __ j(not_equal, slow);
1341 // Load next context in chain. 1341 // Load next context in chain.
1342 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 1342 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
1343 __ jmp(&next); 1343 __ jmp(&next);
1344 __ bind(&fast); 1344 __ bind(&fast);
1345 } 1345 }
1346 1346
1347 // All extension objects were empty and it is safe to use a global 1347 // All extension objects were empty and it is safe to use a normal global
1348 // load IC call. 1348 // load machinery.
1349 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1349 EmitGlobalVariableLoad(proxy, typeof_state);
1350 __ mov(LoadDescriptor::NameRegister(), proxy->var()->name());
1351 __ mov(LoadDescriptor::SlotRegister(),
1352 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
1353
1354 ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
1355 ? NOT_CONTEXTUAL
1356 : CONTEXTUAL;
1357
1358 CallLoadIC(mode);
1359 } 1350 }
1360 1351
1361 1352
1362 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1353 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1363 Label* slow) { 1354 Label* slow) {
1364 DCHECK(var->IsContextSlot()); 1355 DCHECK(var->IsContextSlot());
1365 Register context = esi; 1356 Register context = esi;
1366 Register temp = ebx; 1357 Register temp = ebx;
1367 1358
1368 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1359 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 } else { // LET || CONST 1405 } else { // LET || CONST
1415 __ push(Immediate(var->name())); 1406 __ push(Immediate(var->name()));
1416 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1407 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1417 } 1408 }
1418 } 1409 }
1419 __ jmp(done); 1410 __ jmp(done);
1420 } 1411 }
1421 } 1412 }
1422 1413
1423 1414
1424 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1415 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1416 TypeofState typeof_state) {
1417 Variable* var = proxy->var();
1418 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1419 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1420 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1421 __ mov(LoadDescriptor::NameRegister(), var->name());
1422 __ mov(LoadDescriptor::SlotRegister(),
1423 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
1424 // Inside typeof use a regular load, not a contextual load, to avoid
1425 // a reference error.
1426 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
1427 }
1428
1429
1430 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1431 TypeofState typeof_state) {
1425 SetExpressionPosition(proxy); 1432 SetExpressionPosition(proxy);
1426 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1433 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1427 Variable* var = proxy->var(); 1434 Variable* var = proxy->var();
1428 1435
1429 // Three cases: global variables, lookup variables, and all other types of 1436 // Three cases: global variables, lookup variables, and all other types of
1430 // variables. 1437 // variables.
1431 switch (var->location()) { 1438 switch (var->location()) {
1432 case VariableLocation::GLOBAL: 1439 case VariableLocation::GLOBAL:
1433 case VariableLocation::UNALLOCATED: { 1440 case VariableLocation::UNALLOCATED: {
1434 Comment cmnt(masm_, "[ Global variable"); 1441 Comment cmnt(masm_, "[ Global variable");
1435 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1442 EmitGlobalVariableLoad(proxy, typeof_state);
1436 __ mov(LoadDescriptor::NameRegister(), var->name());
1437 __ mov(LoadDescriptor::SlotRegister(),
1438 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
1439 CallGlobalLoadIC(var->name());
1440 context()->Plug(eax); 1443 context()->Plug(eax);
1441 break; 1444 break;
1442 } 1445 }
1443 1446
1444 case VariableLocation::PARAMETER: 1447 case VariableLocation::PARAMETER:
1445 case VariableLocation::LOCAL: 1448 case VariableLocation::LOCAL:
1446 case VariableLocation::CONTEXT: { 1449 case VariableLocation::CONTEXT: {
1450 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
1447 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1451 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1448 : "[ Stack variable"); 1452 : "[ Stack variable");
1449 if (var->binding_needs_init()) { 1453 if (var->binding_needs_init()) {
1450 // var->scope() may be NULL when the proxy is located in eval code and 1454 // var->scope() may be NULL when the proxy is located in eval code and
1451 // refers to a potential outside binding. Currently those bindings are 1455 // refers to a potential outside binding. Currently those bindings are
1452 // always looked up dynamically, i.e. in that case 1456 // always looked up dynamically, i.e. in that case
1453 // var->location() == LOOKUP. 1457 // var->location() == LOOKUP.
1454 // always holds. 1458 // always holds.
1455 DCHECK(var->scope() != NULL); 1459 DCHECK(var->scope() != NULL);
1456 1460
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 } 1513 }
1510 context()->Plug(var); 1514 context()->Plug(var);
1511 break; 1515 break;
1512 } 1516 }
1513 1517
1514 case VariableLocation::LOOKUP: { 1518 case VariableLocation::LOOKUP: {
1515 Comment cmnt(masm_, "[ Lookup variable"); 1519 Comment cmnt(masm_, "[ Lookup variable");
1516 Label done, slow; 1520 Label done, slow;
1517 // Generate code for loading from variables potentially shadowed 1521 // Generate code for loading from variables potentially shadowed
1518 // by eval-introduced variables. 1522 // by eval-introduced variables.
1519 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); 1523 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
1520 __ bind(&slow); 1524 __ bind(&slow);
1521 __ push(esi); // Context. 1525 __ push(esi); // Context.
1522 __ push(Immediate(var->name())); 1526 __ push(Immediate(var->name()));
1523 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 1527 Runtime::FunctionId function_id =
1528 typeof_state == NOT_INSIDE_TYPEOF
1529 ? Runtime::kLoadLookupSlot
1530 : Runtime::kLoadLookupSlotNoReferenceError;
1531 __ CallRuntime(function_id, 2);
1524 __ bind(&done); 1532 __ bind(&done);
1525 context()->Plug(eax); 1533 context()->Plug(eax);
1526 break; 1534 break;
1527 } 1535 }
1528 } 1536 }
1529 } 1537 }
1530 1538
1531 1539
1532 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1540 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1533 Comment cmnt(masm_, "[ RegExpLiteral"); 1541 Comment cmnt(masm_, "[ RegExpLiteral");
(...skipping 3551 matching lines...) Expand 10 before | Expand all | Expand 10 after
5085 } 5093 }
5086 } else { 5094 } else {
5087 context()->Plug(eax); 5095 context()->Plug(eax);
5088 } 5096 }
5089 break; 5097 break;
5090 } 5098 }
5091 } 5099 }
5092 } 5100 }
5093 5101
5094 5102
5095 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
5096 VariableProxy* proxy = expr->AsVariableProxy();
5097 DCHECK(!context()->IsEffect());
5098 DCHECK(!context()->IsTest());
5099
5100 if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) {
5101 Comment cmnt(masm_, "[ Global variable");
5102 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
5103 __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name()));
5104 __ mov(LoadDescriptor::SlotRegister(),
5105 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
5106 // Use a regular load, not a contextual load, to avoid a reference
5107 // error.
5108 CallLoadIC(NOT_CONTEXTUAL);
5109 PrepareForBailout(expr, TOS_REG);
5110 context()->Plug(eax);
5111 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
5112 Comment cmnt(masm_, "[ Lookup slot");
5113 Label done, slow;
5114
5115 // Generate code for loading from variables potentially shadowed
5116 // by eval-introduced variables.
5117 EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done);
5118
5119 __ bind(&slow);
5120 __ push(esi);
5121 __ push(Immediate(proxy->name()));
5122 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2);
5123 PrepareForBailout(expr, TOS_REG);
5124 __ bind(&done);
5125
5126 context()->Plug(eax);
5127 } else {
5128 // This expression cannot throw a reference error at the top level.
5129 VisitInDuplicateContext(expr);
5130 }
5131 }
5132
5133
5134 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, 5103 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
5135 Expression* sub_expr, 5104 Expression* sub_expr,
5136 Handle<String> check) { 5105 Handle<String> check) {
5137 Label materialize_true, materialize_false; 5106 Label materialize_true, materialize_false;
5138 Label* if_true = NULL; 5107 Label* if_true = NULL;
5139 Label* if_false = NULL; 5108 Label* if_false = NULL;
5140 Label* fall_through = NULL; 5109 Label* fall_through = NULL;
5141 context()->PrepareTest(&materialize_true, &materialize_false, 5110 context()->PrepareTest(&materialize_true, &materialize_false,
5142 &if_true, &if_false, &fall_through); 5111 &if_true, &if_false, &fall_through);
5143 5112
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
5492 Assembler::target_address_at(call_target_address, 5461 Assembler::target_address_at(call_target_address,
5493 unoptimized_code)); 5462 unoptimized_code));
5494 return OSR_AFTER_STACK_CHECK; 5463 return OSR_AFTER_STACK_CHECK;
5495 } 5464 }
5496 5465
5497 5466
5498 } // namespace internal 5467 } // namespace internal
5499 } // namespace v8 5468 } // namespace v8
5500 5469
5501 #endif // V8_TARGET_ARCH_IA32 5470 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.cc ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698