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

Side by Side Diff: src/x64/full-codegen-x64.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/ppc/full-codegen-ppc.cc ('k') | src/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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
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 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 __ j(equal, &fast, Label::kNear); 1374 __ j(equal, &fast, Label::kNear);
1375 // Check that extension is NULL. 1375 // Check that extension is NULL.
1376 __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1376 __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
1377 __ j(not_equal, slow); 1377 __ j(not_equal, slow);
1378 // Load next context in chain. 1378 // Load next context in chain.
1379 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 1379 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
1380 __ jmp(&next); 1380 __ jmp(&next);
1381 __ bind(&fast); 1381 __ bind(&fast);
1382 } 1382 }
1383 1383
1384 // All extension objects were empty and it is safe to use a global 1384 // All extension objects were empty and it is safe to use a normal global
1385 // load IC call. 1385 // load machinery.
1386 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1386 EmitGlobalVariableLoad(proxy, typeof_state);
1387 __ Move(LoadDescriptor::NameRegister(), proxy->var()->name());
1388 __ Move(LoadDescriptor::SlotRegister(),
1389 SmiFromSlot(proxy->VariableFeedbackSlot()));
1390
1391 ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
1392 ? NOT_CONTEXTUAL
1393 : CONTEXTUAL;
1394 CallLoadIC(mode);
1395 } 1387 }
1396 1388
1397 1389
1398 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1390 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1399 Label* slow) { 1391 Label* slow) {
1400 DCHECK(var->IsContextSlot()); 1392 DCHECK(var->IsContextSlot());
1401 Register context = rsi; 1393 Register context = rsi;
1402 Register temp = rbx; 1394 Register temp = rbx;
1403 1395
1404 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1396 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 } else { // LET || CONST 1442 } else { // LET || CONST
1451 __ Push(var->name()); 1443 __ Push(var->name());
1452 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1444 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1453 } 1445 }
1454 } 1446 }
1455 __ jmp(done); 1447 __ jmp(done);
1456 } 1448 }
1457 } 1449 }
1458 1450
1459 1451
1460 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1452 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1453 TypeofState typeof_state) {
1454 Variable* var = proxy->var();
1455 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1456 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1457 __ Move(LoadDescriptor::NameRegister(), var->name());
1458 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1459 __ Move(LoadDescriptor::SlotRegister(),
1460 SmiFromSlot(proxy->VariableFeedbackSlot()));
1461 // Inside typeof use a regular load, not a contextual load, to avoid
1462 // a reference error.
1463 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
1464 }
1465
1466
1467 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1468 TypeofState typeof_state) {
1461 // Record position before possible IC call. 1469 // Record position before possible IC call.
1462 SetExpressionPosition(proxy); 1470 SetExpressionPosition(proxy);
1463 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1471 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1464 Variable* var = proxy->var(); 1472 Variable* var = proxy->var();
1465 1473
1466 // Three cases: global variables, lookup variables, and all other types of 1474 // Three cases: global variables, lookup variables, and all other types of
1467 // variables. 1475 // variables.
1468 switch (var->location()) { 1476 switch (var->location()) {
1469 case VariableLocation::GLOBAL: 1477 case VariableLocation::GLOBAL:
1470 case VariableLocation::UNALLOCATED: { 1478 case VariableLocation::UNALLOCATED: {
1471 Comment cmnt(masm_, "[ Global variable"); 1479 Comment cmnt(masm_, "[ Global variable");
1472 __ Move(LoadDescriptor::NameRegister(), var->name()); 1480 EmitGlobalVariableLoad(proxy, typeof_state);
1473 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1474 __ Move(LoadDescriptor::SlotRegister(),
1475 SmiFromSlot(proxy->VariableFeedbackSlot()));
1476 CallGlobalLoadIC(var->name());
1477 context()->Plug(rax); 1481 context()->Plug(rax);
1478 break; 1482 break;
1479 } 1483 }
1480 1484
1481 case VariableLocation::PARAMETER: 1485 case VariableLocation::PARAMETER:
1482 case VariableLocation::LOCAL: 1486 case VariableLocation::LOCAL:
1483 case VariableLocation::CONTEXT: { 1487 case VariableLocation::CONTEXT: {
1488 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
1484 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" 1489 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot"
1485 : "[ Stack slot"); 1490 : "[ Stack slot");
1486 if (var->binding_needs_init()) { 1491 if (var->binding_needs_init()) {
1487 // var->scope() may be NULL when the proxy is located in eval code and 1492 // var->scope() may be NULL when the proxy is located in eval code and
1488 // refers to a potential outside binding. Currently those bindings are 1493 // refers to a potential outside binding. Currently those bindings are
1489 // always looked up dynamically, i.e. in that case 1494 // always looked up dynamically, i.e. in that case
1490 // var->location() == LOOKUP. 1495 // var->location() == LOOKUP.
1491 // always holds. 1496 // always holds.
1492 DCHECK(var->scope() != NULL); 1497 DCHECK(var->scope() != NULL);
1493 1498
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 } 1551 }
1547 context()->Plug(var); 1552 context()->Plug(var);
1548 break; 1553 break;
1549 } 1554 }
1550 1555
1551 case VariableLocation::LOOKUP: { 1556 case VariableLocation::LOOKUP: {
1552 Comment cmnt(masm_, "[ Lookup slot"); 1557 Comment cmnt(masm_, "[ Lookup slot");
1553 Label done, slow; 1558 Label done, slow;
1554 // Generate code for loading from variables potentially shadowed 1559 // Generate code for loading from variables potentially shadowed
1555 // by eval-introduced variables. 1560 // by eval-introduced variables.
1556 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); 1561 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
1557 __ bind(&slow); 1562 __ bind(&slow);
1558 __ Push(rsi); // Context. 1563 __ Push(rsi); // Context.
1559 __ Push(var->name()); 1564 __ Push(var->name());
1560 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 1565 Runtime::FunctionId function_id =
1566 typeof_state == NOT_INSIDE_TYPEOF
1567 ? Runtime::kLoadLookupSlot
1568 : Runtime::kLoadLookupSlotNoReferenceError;
1569 __ CallRuntime(function_id, 2);
1561 __ bind(&done); 1570 __ bind(&done);
1562 context()->Plug(rax); 1571 context()->Plug(rax);
1563 break; 1572 break;
1564 } 1573 }
1565 } 1574 }
1566 } 1575 }
1567 1576
1568 1577
1569 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1578 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1570 Comment cmnt(masm_, "[ RegExpLiteral"); 1579 Comment cmnt(masm_, "[ RegExpLiteral");
(...skipping 3534 matching lines...) Expand 10 before | Expand all | Expand 10 after
5105 } 5114 }
5106 } else { 5115 } else {
5107 context()->Plug(rax); 5116 context()->Plug(rax);
5108 } 5117 }
5109 break; 5118 break;
5110 } 5119 }
5111 } 5120 }
5112 } 5121 }
5113 5122
5114 5123
5115 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
5116 VariableProxy* proxy = expr->AsVariableProxy();
5117 DCHECK(!context()->IsEffect());
5118 DCHECK(!context()->IsTest());
5119
5120 if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) {
5121 Comment cmnt(masm_, "[ Global variable");
5122 __ Move(LoadDescriptor::NameRegister(), proxy->name());
5123 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
5124 __ Move(LoadDescriptor::SlotRegister(),
5125 SmiFromSlot(proxy->VariableFeedbackSlot()));
5126 // Use a regular load, not a contextual load, to avoid a reference
5127 // error.
5128 CallLoadIC(NOT_CONTEXTUAL);
5129 PrepareForBailout(expr, TOS_REG);
5130 context()->Plug(rax);
5131 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
5132 Comment cmnt(masm_, "[ Lookup slot");
5133 Label done, slow;
5134
5135 // Generate code for loading from variables potentially shadowed
5136 // by eval-introduced variables.
5137 EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done);
5138
5139 __ bind(&slow);
5140 __ Push(rsi);
5141 __ Push(proxy->name());
5142 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2);
5143 PrepareForBailout(expr, TOS_REG);
5144 __ bind(&done);
5145
5146 context()->Plug(rax);
5147 } else {
5148 // This expression cannot throw a reference error at the top level.
5149 VisitInDuplicateContext(expr);
5150 }
5151 }
5152
5153
5154 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, 5124 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
5155 Expression* sub_expr, 5125 Expression* sub_expr,
5156 Handle<String> check) { 5126 Handle<String> check) {
5157 Label materialize_true, materialize_false; 5127 Label materialize_true, materialize_false;
5158 Label* if_true = NULL; 5128 Label* if_true = NULL;
5159 Label* if_false = NULL; 5129 Label* if_false = NULL;
5160 Label* fall_through = NULL; 5130 Label* fall_through = NULL;
5161 context()->PrepareTest(&materialize_true, &materialize_false, 5131 context()->PrepareTest(&materialize_true, &materialize_false,
5162 &if_true, &if_false, &fall_through); 5132 &if_true, &if_false, &fall_through);
5163 5133
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
5513 Assembler::target_address_at(call_target_address, 5483 Assembler::target_address_at(call_target_address,
5514 unoptimized_code)); 5484 unoptimized_code));
5515 return OSR_AFTER_STACK_CHECK; 5485 return OSR_AFTER_STACK_CHECK;
5516 } 5486 }
5517 5487
5518 5488
5519 } // namespace internal 5489 } // namespace internal
5520 } // namespace v8 5490 } // namespace v8
5521 5491
5522 #endif // V8_TARGET_ARCH_X64 5492 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ppc/full-codegen-ppc.cc ('k') | src/x87/full-codegen-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698