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

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

Issue 1227893005: TypeofMode replaces TypeofState and ContextualMode. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: minor fix 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
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 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 isolate()->factory()->home_object_symbol()); 1326 isolate()->factory()->home_object_symbol());
1327 __ movp(StoreDescriptor::ValueRegister(), 1327 __ movp(StoreDescriptor::ValueRegister(),
1328 Operand(rsp, offset * kPointerSize)); 1328 Operand(rsp, offset * kPointerSize));
1329 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); 1329 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1330 CallStoreIC(); 1330 CallStoreIC();
1331 } 1331 }
1332 } 1332 }
1333 1333
1334 1334
1335 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1335 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1336 TypeofState typeof_state, 1336 TypeofMode typeof_mode,
1337 Label* slow) { 1337 Label* slow) {
1338 Register context = rsi; 1338 Register context = rsi;
1339 Register temp = rdx; 1339 Register temp = rdx;
1340 1340
1341 Scope* s = scope(); 1341 Scope* s = scope();
1342 while (s != NULL) { 1342 while (s != NULL) {
1343 if (s->num_heap_slots() > 0) { 1343 if (s->num_heap_slots() > 0) {
1344 if (s->calls_sloppy_eval()) { 1344 if (s->calls_sloppy_eval()) {
1345 // Check that extension is NULL. 1345 // Check that extension is NULL.
1346 __ cmpp(ContextOperand(context, Context::EXTENSION_INDEX), 1346 __ cmpp(ContextOperand(context, Context::EXTENSION_INDEX),
(...skipping 29 matching lines...) Expand all
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 normal global 1384 // All extension objects were empty and it is safe to use a normal global
1385 // load machinery. 1385 // load machinery.
1386 EmitGlobalVariableLoad(proxy, typeof_state); 1386 EmitGlobalVariableLoad(proxy, typeof_mode);
1387 } 1387 }
1388 1388
1389 1389
1390 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1390 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1391 Label* slow) { 1391 Label* slow) {
1392 DCHECK(var->IsContextSlot()); 1392 DCHECK(var->IsContextSlot());
1393 Register context = rsi; 1393 Register context = rsi;
1394 Register temp = rbx; 1394 Register temp = rbx;
1395 1395
1396 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1396 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
(...skipping 14 matching lines...) Expand all
1411 __ j(not_equal, slow); 1411 __ j(not_equal, slow);
1412 1412
1413 // This function is used only for loads, not stores, so it's safe to 1413 // This function is used only for loads, not stores, so it's safe to
1414 // return an rsi-based operand (the write barrier cannot be allowed to 1414 // return an rsi-based operand (the write barrier cannot be allowed to
1415 // destroy the rsi register). 1415 // destroy the rsi register).
1416 return ContextOperand(context, var->index()); 1416 return ContextOperand(context, var->index());
1417 } 1417 }
1418 1418
1419 1419
1420 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, 1420 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1421 TypeofState typeof_state, 1421 TypeofMode typeof_mode,
1422 Label* slow, 1422 Label* slow, Label* done) {
1423 Label* done) {
1424 // Generate fast-case code for variables that might be shadowed by 1423 // Generate fast-case code for variables that might be shadowed by
1425 // eval-introduced variables. Eval is used a lot without 1424 // eval-introduced variables. Eval is used a lot without
1426 // introducing variables. In those cases, we do not want to 1425 // introducing variables. In those cases, we do not want to
1427 // perform a runtime call for all variables in the scope 1426 // perform a runtime call for all variables in the scope
1428 // containing the eval. 1427 // containing the eval.
1429 Variable* var = proxy->var(); 1428 Variable* var = proxy->var();
1430 if (var->mode() == DYNAMIC_GLOBAL) { 1429 if (var->mode() == DYNAMIC_GLOBAL) {
1431 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); 1430 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1432 __ jmp(done); 1431 __ jmp(done);
1433 } else if (var->mode() == DYNAMIC_LOCAL) { 1432 } else if (var->mode() == DYNAMIC_LOCAL) {
1434 Variable* local = var->local_if_not_shadowed(); 1433 Variable* local = var->local_if_not_shadowed();
1435 __ movp(rax, ContextSlotOperandCheckExtensions(local, slow)); 1434 __ movp(rax, ContextSlotOperandCheckExtensions(local, slow));
1436 if (local->mode() == LET || local->mode() == CONST || 1435 if (local->mode() == LET || local->mode() == CONST ||
1437 local->mode() == CONST_LEGACY) { 1436 local->mode() == CONST_LEGACY) {
1438 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 1437 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1439 __ j(not_equal, done); 1438 __ j(not_equal, done);
1440 if (local->mode() == CONST_LEGACY) { 1439 if (local->mode() == CONST_LEGACY) {
1441 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1440 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1442 } else { // LET || CONST 1441 } else { // LET || CONST
1443 __ Push(var->name()); 1442 __ Push(var->name());
1444 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1443 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1445 } 1444 }
1446 } 1445 }
1447 __ jmp(done); 1446 __ jmp(done);
1448 } 1447 }
1449 } 1448 }
1450 1449
1451 1450
1452 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1451 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1453 TypeofState typeof_state) { 1452 TypeofMode typeof_mode) {
1454 Variable* var = proxy->var(); 1453 Variable* var = proxy->var();
1455 DCHECK(var->IsUnallocatedOrGlobalSlot() || 1454 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1456 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); 1455 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1457 __ Move(LoadDescriptor::NameRegister(), var->name()); 1456 __ Move(LoadDescriptor::NameRegister(), var->name());
1458 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1457 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1459 __ Move(LoadDescriptor::SlotRegister(), 1458 __ Move(LoadDescriptor::SlotRegister(),
1460 SmiFromSlot(proxy->VariableFeedbackSlot())); 1459 SmiFromSlot(proxy->VariableFeedbackSlot()));
1461 // Inside typeof use a regular load, not a contextual load, to avoid 1460 CallLoadIC(typeof_mode);
1462 // a reference error.
1463 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
1464 } 1461 }
1465 1462
1466 1463
1467 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1464 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1468 TypeofState typeof_state) { 1465 TypeofMode typeof_mode) {
1469 // Record position before possible IC call. 1466 // Record position before possible IC call.
1470 SetExpressionPosition(proxy); 1467 SetExpressionPosition(proxy);
1471 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1468 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1472 Variable* var = proxy->var(); 1469 Variable* var = proxy->var();
1473 1470
1474 // Three cases: global variables, lookup variables, and all other types of 1471 // Three cases: global variables, lookup variables, and all other types of
1475 // variables. 1472 // variables.
1476 switch (var->location()) { 1473 switch (var->location()) {
1477 case VariableLocation::GLOBAL: 1474 case VariableLocation::GLOBAL:
1478 case VariableLocation::UNALLOCATED: { 1475 case VariableLocation::UNALLOCATED: {
1479 Comment cmnt(masm_, "[ Global variable"); 1476 Comment cmnt(masm_, "[ Global variable");
1480 EmitGlobalVariableLoad(proxy, typeof_state); 1477 EmitGlobalVariableLoad(proxy, typeof_mode);
1481 context()->Plug(rax); 1478 context()->Plug(rax);
1482 break; 1479 break;
1483 } 1480 }
1484 1481
1485 case VariableLocation::PARAMETER: 1482 case VariableLocation::PARAMETER:
1486 case VariableLocation::LOCAL: 1483 case VariableLocation::LOCAL:
1487 case VariableLocation::CONTEXT: { 1484 case VariableLocation::CONTEXT: {
1488 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); 1485 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1489 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" 1486 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot"
1490 : "[ Stack slot"); 1487 : "[ Stack slot");
1491 if (var->binding_needs_init()) { 1488 if (var->binding_needs_init()) {
1492 // var->scope() may be NULL when the proxy is located in eval code and 1489 // var->scope() may be NULL when the proxy is located in eval code and
1493 // refers to a potential outside binding. Currently those bindings are 1490 // refers to a potential outside binding. Currently those bindings are
1494 // always looked up dynamically, i.e. in that case 1491 // always looked up dynamically, i.e. in that case
1495 // var->location() == LOOKUP. 1492 // var->location() == LOOKUP.
1496 // always holds. 1493 // always holds.
1497 DCHECK(var->scope() != NULL); 1494 DCHECK(var->scope() != NULL);
1498 1495
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 } 1548 }
1552 context()->Plug(var); 1549 context()->Plug(var);
1553 break; 1550 break;
1554 } 1551 }
1555 1552
1556 case VariableLocation::LOOKUP: { 1553 case VariableLocation::LOOKUP: {
1557 Comment cmnt(masm_, "[ Lookup slot"); 1554 Comment cmnt(masm_, "[ Lookup slot");
1558 Label done, slow; 1555 Label done, slow;
1559 // Generate code for loading from variables potentially shadowed 1556 // Generate code for loading from variables potentially shadowed
1560 // by eval-introduced variables. 1557 // by eval-introduced variables.
1561 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); 1558 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1562 __ bind(&slow); 1559 __ bind(&slow);
1563 __ Push(rsi); // Context. 1560 __ Push(rsi); // Context.
1564 __ Push(var->name()); 1561 __ Push(var->name());
1565 Runtime::FunctionId function_id = 1562 Runtime::FunctionId function_id =
1566 typeof_state == NOT_INSIDE_TYPEOF 1563 typeof_mode == NOT_INSIDE_TYPEOF
1567 ? Runtime::kLoadLookupSlot 1564 ? Runtime::kLoadLookupSlot
1568 : Runtime::kLoadLookupSlotNoReferenceError; 1565 : Runtime::kLoadLookupSlotNoReferenceError;
1569 __ CallRuntime(function_id, 2); 1566 __ CallRuntime(function_id, 2);
1570 __ bind(&done); 1567 __ bind(&done);
1571 context()->Plug(rax); 1568 context()->Plug(rax);
1572 break; 1569 break;
1573 } 1570 }
1574 } 1571 }
1575 } 1572 }
1576 1573
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
2234 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2231 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2235 __ Drop(1); // The function is still on the stack; drop it. 2232 __ Drop(1); // The function is still on the stack; drop it.
2236 2233
2237 // if (!result.done) goto l_try; 2234 // if (!result.done) goto l_try;
2238 __ bind(&l_loop); 2235 __ bind(&l_loop);
2239 __ Move(load_receiver, rax); 2236 __ Move(load_receiver, rax);
2240 __ Push(load_receiver); // save result 2237 __ Push(load_receiver); // save result
2241 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" 2238 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
2242 __ Move(LoadDescriptor::SlotRegister(), 2239 __ Move(LoadDescriptor::SlotRegister(),
2243 SmiFromSlot(expr->DoneFeedbackSlot())); 2240 SmiFromSlot(expr->DoneFeedbackSlot()));
2244 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done 2241 CallLoadIC(INSIDE_TYPEOF); // rax=result.done
2245 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2242 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2246 CallIC(bool_ic); 2243 CallIC(bool_ic);
2247 __ testp(result_register(), result_register()); 2244 __ testp(result_register(), result_register());
2248 __ j(zero, &l_try); 2245 __ j(zero, &l_try);
2249 2246
2250 // result.value 2247 // result.value
2251 __ Pop(load_receiver); // result 2248 __ Pop(load_receiver); // result
2252 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" 2249 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
2253 __ Move(LoadDescriptor::SlotRegister(), 2250 __ Move(LoadDescriptor::SlotRegister(),
2254 SmiFromSlot(expr->ValueFeedbackSlot())); 2251 SmiFromSlot(expr->ValueFeedbackSlot()));
2255 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax 2252 CallLoadIC(INSIDE_TYPEOF); // result.value in rax
2256 context()->DropAndPlug(2, rax); // drop iter and g 2253 context()->DropAndPlug(2, rax); // drop iter and g
2257 break; 2254 break;
2258 } 2255 }
2259 } 2256 }
2260 } 2257 }
2261 2258
2262 2259
2263 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2260 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2264 Expression *value, 2261 Expression *value,
2265 JSGeneratorObject::ResumeMode resume_mode) { 2262 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2385 2382
2386 2383
2387 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2384 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2388 SetExpressionPosition(prop); 2385 SetExpressionPosition(prop);
2389 Literal* key = prop->key()->AsLiteral(); 2386 Literal* key = prop->key()->AsLiteral();
2390 DCHECK(!prop->IsSuperAccess()); 2387 DCHECK(!prop->IsSuperAccess());
2391 2388
2392 __ Move(LoadDescriptor::NameRegister(), key->value()); 2389 __ Move(LoadDescriptor::NameRegister(), key->value());
2393 __ Move(LoadDescriptor::SlotRegister(), 2390 __ Move(LoadDescriptor::SlotRegister(),
2394 SmiFromSlot(prop->PropertyFeedbackSlot())); 2391 SmiFromSlot(prop->PropertyFeedbackSlot()));
2395 CallLoadIC(NOT_CONTEXTUAL, language_mode()); 2392 CallLoadIC(INSIDE_TYPEOF, language_mode());
2396 } 2393 }
2397 2394
2398 2395
2399 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2396 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2400 // Stack: receiver, home_object 2397 // Stack: receiver, home_object
2401 SetExpressionPosition(prop); 2398 SetExpressionPosition(prop);
2402 Literal* key = prop->key()->AsLiteral(); 2399 Literal* key = prop->key()->AsLiteral();
2403 DCHECK(!key->value()->IsSmi()); 2400 DCHECK(!key->value()->IsSmi());
2404 DCHECK(prop->IsSuperAccess()); 2401 DCHECK(prop->IsSuperAccess());
2405 2402
(...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after
4673 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 4670 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4674 // Push the builtins object as receiver. 4671 // Push the builtins object as receiver.
4675 __ movp(rax, GlobalObjectOperand()); 4672 __ movp(rax, GlobalObjectOperand());
4676 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); 4673 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
4677 4674
4678 // Load the function from the receiver. 4675 // Load the function from the receiver.
4679 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 4676 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
4680 __ Move(LoadDescriptor::NameRegister(), expr->name()); 4677 __ Move(LoadDescriptor::NameRegister(), expr->name());
4681 __ Move(LoadDescriptor::SlotRegister(), 4678 __ Move(LoadDescriptor::SlotRegister(),
4682 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); 4679 SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
4683 CallLoadIC(NOT_CONTEXTUAL); 4680 CallLoadIC(INSIDE_TYPEOF);
4684 } 4681 }
4685 4682
4686 4683
4687 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 4684 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
4688 ZoneList<Expression*>* args = expr->arguments(); 4685 ZoneList<Expression*>* args = expr->arguments();
4689 int arg_count = args->length(); 4686 int arg_count = args->length();
4690 4687
4691 SetExpressionPosition(expr); 4688 SetExpressionPosition(expr);
4692 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4689 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
4693 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 4690 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after
5483 Assembler::target_address_at(call_target_address, 5480 Assembler::target_address_at(call_target_address,
5484 unoptimized_code)); 5481 unoptimized_code));
5485 return OSR_AFTER_STACK_CHECK; 5482 return OSR_AFTER_STACK_CHECK;
5486 } 5483 }
5487 5484
5488 5485
5489 } // namespace internal 5486 } // namespace internal
5490 } // namespace v8 5487 } // namespace v8
5491 5488
5492 #endif // V8_TARGET_ARCH_X64 5489 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/ic/ic.cc ('K') | « src/x64/codegen-x64.h ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698