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

Side by Side Diff: src/arm64/full-codegen-arm64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 7 #if V8_TARGET_ARCH_ARM64
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 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 __ Mov(StoreDescriptor::NameRegister(), 1350 __ Mov(StoreDescriptor::NameRegister(),
1351 Operand(isolate()->factory()->home_object_symbol())); 1351 Operand(isolate()->factory()->home_object_symbol()));
1352 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); 1352 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize);
1353 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); 1353 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1354 CallStoreIC(); 1354 CallStoreIC();
1355 } 1355 }
1356 } 1356 }
1357 1357
1358 1358
1359 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1359 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1360 TypeofState typeof_state, 1360 TypeofMode typeof_mode,
1361 Label* slow) { 1361 Label* slow) {
1362 Register current = cp; 1362 Register current = cp;
1363 Register next = x10; 1363 Register next = x10;
1364 Register temp = x11; 1364 Register temp = x11;
1365 1365
1366 Scope* s = scope(); 1366 Scope* s = scope();
1367 while (s != NULL) { 1367 while (s != NULL) {
1368 if (s->num_heap_slots() > 0) { 1368 if (s->num_heap_slots() > 0) {
1369 if (s->calls_sloppy_eval()) { 1369 if (s->calls_sloppy_eval()) {
1370 // Check that extension is NULL. 1370 // Check that extension is NULL.
(...skipping 23 matching lines...) Expand all
1394 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); 1394 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX));
1395 __ Cbnz(temp, slow); 1395 __ Cbnz(temp, slow);
1396 // Load next context in chain. 1396 // Load next context in chain.
1397 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); 1397 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX));
1398 __ B(&loop); 1398 __ B(&loop);
1399 __ Bind(&fast); 1399 __ Bind(&fast);
1400 } 1400 }
1401 1401
1402 // All extension objects were empty and it is safe to use a normal global 1402 // All extension objects were empty and it is safe to use a normal global
1403 // load machinery. 1403 // load machinery.
1404 EmitGlobalVariableLoad(proxy, typeof_state); 1404 EmitGlobalVariableLoad(proxy, typeof_mode);
1405 } 1405 }
1406 1406
1407 1407
1408 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1408 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1409 Label* slow) { 1409 Label* slow) {
1410 DCHECK(var->IsContextSlot()); 1410 DCHECK(var->IsContextSlot());
1411 Register context = cp; 1411 Register context = cp;
1412 Register next = x10; 1412 Register next = x10;
1413 Register temp = x11; 1413 Register temp = x11;
1414 1414
(...skipping 14 matching lines...) Expand all
1429 __ Cbnz(temp, slow); 1429 __ Cbnz(temp, slow);
1430 1430
1431 // This function is used only for loads, not stores, so it's safe to 1431 // This function is used only for loads, not stores, so it's safe to
1432 // return an cp-based operand (the write barrier cannot be allowed to 1432 // return an cp-based operand (the write barrier cannot be allowed to
1433 // destroy the cp register). 1433 // destroy the cp register).
1434 return ContextMemOperand(context, var->index()); 1434 return ContextMemOperand(context, var->index());
1435 } 1435 }
1436 1436
1437 1437
1438 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, 1438 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1439 TypeofState typeof_state, 1439 TypeofMode typeof_mode,
1440 Label* slow, 1440 Label* slow, Label* done) {
1441 Label* done) {
1442 // Generate fast-case code for variables that might be shadowed by 1441 // Generate fast-case code for variables that might be shadowed by
1443 // eval-introduced variables. Eval is used a lot without 1442 // eval-introduced variables. Eval is used a lot without
1444 // introducing variables. In those cases, we do not want to 1443 // introducing variables. In those cases, we do not want to
1445 // perform a runtime call for all variables in the scope 1444 // perform a runtime call for all variables in the scope
1446 // containing the eval. 1445 // containing the eval.
1447 Variable* var = proxy->var(); 1446 Variable* var = proxy->var();
1448 if (var->mode() == DYNAMIC_GLOBAL) { 1447 if (var->mode() == DYNAMIC_GLOBAL) {
1449 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); 1448 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1450 __ B(done); 1449 __ B(done);
1451 } else if (var->mode() == DYNAMIC_LOCAL) { 1450 } else if (var->mode() == DYNAMIC_LOCAL) {
1452 Variable* local = var->local_if_not_shadowed(); 1451 Variable* local = var->local_if_not_shadowed();
1453 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow)); 1452 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow));
1454 if (local->mode() == LET || local->mode() == CONST || 1453 if (local->mode() == LET || local->mode() == CONST ||
1455 local->mode() == CONST_LEGACY) { 1454 local->mode() == CONST_LEGACY) {
1456 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done); 1455 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done);
1457 if (local->mode() == CONST_LEGACY) { 1456 if (local->mode() == CONST_LEGACY) {
1458 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1457 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1459 } else { // LET || CONST 1458 } else { // LET || CONST
1460 __ Mov(x0, Operand(var->name())); 1459 __ Mov(x0, Operand(var->name()));
1461 __ Push(x0); 1460 __ Push(x0);
1462 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1461 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1463 } 1462 }
1464 } 1463 }
1465 __ B(done); 1464 __ B(done);
1466 } 1465 }
1467 } 1466 }
1468 1467
1469 1468
1470 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1469 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1471 TypeofState typeof_state) { 1470 TypeofMode typeof_mode) {
1472 Variable* var = proxy->var(); 1471 Variable* var = proxy->var();
1473 DCHECK(var->IsUnallocatedOrGlobalSlot() || 1472 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1474 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); 1473 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1475 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); 1474 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand());
1476 __ Mov(LoadDescriptor::NameRegister(), Operand(var->name())); 1475 __ Mov(LoadDescriptor::NameRegister(), Operand(var->name()));
1477 __ Mov(LoadDescriptor::SlotRegister(), 1476 __ Mov(LoadDescriptor::SlotRegister(),
1478 SmiFromSlot(proxy->VariableFeedbackSlot())); 1477 SmiFromSlot(proxy->VariableFeedbackSlot()));
1479 // Inside typeof use a regular load, not a contextual load, to avoid 1478 CallLoadIC(typeof_mode);
1480 // a reference error.
1481 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
1482 } 1479 }
1483 1480
1484 1481
1485 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1482 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1486 TypeofState typeof_state) { 1483 TypeofMode typeof_mode) {
1487 // Record position before possible IC call. 1484 // Record position before possible IC call.
1488 SetExpressionPosition(proxy); 1485 SetExpressionPosition(proxy);
1489 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1486 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1490 Variable* var = proxy->var(); 1487 Variable* var = proxy->var();
1491 1488
1492 // Three cases: global variables, lookup variables, and all other types of 1489 // Three cases: global variables, lookup variables, and all other types of
1493 // variables. 1490 // variables.
1494 switch (var->location()) { 1491 switch (var->location()) {
1495 case VariableLocation::GLOBAL: 1492 case VariableLocation::GLOBAL:
1496 case VariableLocation::UNALLOCATED: { 1493 case VariableLocation::UNALLOCATED: {
1497 Comment cmnt(masm_, "Global variable"); 1494 Comment cmnt(masm_, "Global variable");
1498 EmitGlobalVariableLoad(proxy, typeof_state); 1495 EmitGlobalVariableLoad(proxy, typeof_mode);
1499 context()->Plug(x0); 1496 context()->Plug(x0);
1500 break; 1497 break;
1501 } 1498 }
1502 1499
1503 case VariableLocation::PARAMETER: 1500 case VariableLocation::PARAMETER:
1504 case VariableLocation::LOCAL: 1501 case VariableLocation::LOCAL:
1505 case VariableLocation::CONTEXT: { 1502 case VariableLocation::CONTEXT: {
1506 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); 1503 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1507 Comment cmnt(masm_, var->IsContextSlot() 1504 Comment cmnt(masm_, var->IsContextSlot()
1508 ? "Context variable" 1505 ? "Context variable"
1509 : "Stack variable"); 1506 : "Stack variable");
1510 if (var->binding_needs_init()) { 1507 if (var->binding_needs_init()) {
1511 // var->scope() may be NULL when the proxy is located in eval code and 1508 // var->scope() may be NULL when the proxy is located in eval code and
1512 // refers to a potential outside binding. Currently those bindings are 1509 // refers to a potential outside binding. Currently those bindings are
1513 // always looked up dynamically, i.e. in that case 1510 // always looked up dynamically, i.e. in that case
1514 // var->location() == LOOKUP. 1511 // var->location() == LOOKUP.
1515 // always holds. 1512 // always holds.
1516 DCHECK(var->scope() != NULL); 1513 DCHECK(var->scope() != NULL);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 } 1567 }
1571 } 1568 }
1572 context()->Plug(var); 1569 context()->Plug(var);
1573 break; 1570 break;
1574 } 1571 }
1575 1572
1576 case VariableLocation::LOOKUP: { 1573 case VariableLocation::LOOKUP: {
1577 Label done, slow; 1574 Label done, slow;
1578 // Generate code for loading from variables potentially shadowed by 1575 // Generate code for loading from variables potentially shadowed by
1579 // eval-introduced variables. 1576 // eval-introduced variables.
1580 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); 1577 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1581 __ Bind(&slow); 1578 __ Bind(&slow);
1582 Comment cmnt(masm_, "Lookup variable"); 1579 Comment cmnt(masm_, "Lookup variable");
1583 __ Mov(x1, Operand(var->name())); 1580 __ Mov(x1, Operand(var->name()));
1584 __ Push(cp, x1); // Context and name. 1581 __ Push(cp, x1); // Context and name.
1585 Runtime::FunctionId function_id = 1582 Runtime::FunctionId function_id =
1586 typeof_state == NOT_INSIDE_TYPEOF 1583 typeof_mode == NOT_INSIDE_TYPEOF
1587 ? Runtime::kLoadLookupSlot 1584 ? Runtime::kLoadLookupSlot
1588 : Runtime::kLoadLookupSlotNoReferenceError; 1585 : Runtime::kLoadLookupSlotNoReferenceError;
1589 __ CallRuntime(function_id, 2); 1586 __ CallRuntime(function_id, 2);
1590 __ Bind(&done); 1587 __ Bind(&done);
1591 context()->Plug(x0); 1588 context()->Plug(x0);
1592 break; 1589 break;
1593 } 1590 }
1594 } 1591 }
1595 } 1592 }
1596 1593
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
2113 2110
2114 2111
2115 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2112 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2116 SetExpressionPosition(prop); 2113 SetExpressionPosition(prop);
2117 Literal* key = prop->key()->AsLiteral(); 2114 Literal* key = prop->key()->AsLiteral();
2118 DCHECK(!prop->IsSuperAccess()); 2115 DCHECK(!prop->IsSuperAccess());
2119 2116
2120 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); 2117 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
2121 __ Mov(LoadDescriptor::SlotRegister(), 2118 __ Mov(LoadDescriptor::SlotRegister(),
2122 SmiFromSlot(prop->PropertyFeedbackSlot())); 2119 SmiFromSlot(prop->PropertyFeedbackSlot()));
2123 CallLoadIC(NOT_CONTEXTUAL, language_mode()); 2120 CallLoadIC(INSIDE_TYPEOF, language_mode());
2124 } 2121 }
2125 2122
2126 2123
2127 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2124 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2128 // Stack: receiver, home_object. 2125 // Stack: receiver, home_object.
2129 SetExpressionPosition(prop); 2126 SetExpressionPosition(prop);
2130 Literal* key = prop->key()->AsLiteral(); 2127 Literal* key = prop->key()->AsLiteral();
2131 DCHECK(!key->value()->IsSmi()); 2128 DCHECK(!key->value()->IsSmi());
2132 DCHECK(prop->IsSuperAccess()); 2129 DCHECK(prop->IsSuperAccess());
2133 2130
(...skipping 2275 matching lines...) Expand 10 before | Expand all | Expand 10 after
4409 __ Ldr(x10, GlobalObjectMemOperand()); 4406 __ Ldr(x10, GlobalObjectMemOperand());
4410 __ Ldr(LoadDescriptor::ReceiverRegister(), 4407 __ Ldr(LoadDescriptor::ReceiverRegister(),
4411 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); 4408 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset));
4412 __ Push(LoadDescriptor::ReceiverRegister()); 4409 __ Push(LoadDescriptor::ReceiverRegister());
4413 4410
4414 // Load the function from the receiver. 4411 // Load the function from the receiver.
4415 Handle<String> name = expr->name(); 4412 Handle<String> name = expr->name();
4416 __ Mov(LoadDescriptor::NameRegister(), Operand(name)); 4413 __ Mov(LoadDescriptor::NameRegister(), Operand(name));
4417 __ Mov(LoadDescriptor::SlotRegister(), 4414 __ Mov(LoadDescriptor::SlotRegister(),
4418 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); 4415 SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
4419 CallLoadIC(NOT_CONTEXTUAL); 4416 CallLoadIC(INSIDE_TYPEOF);
4420 } 4417 }
4421 4418
4422 4419
4423 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 4420 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
4424 ZoneList<Expression*>* args = expr->arguments(); 4421 ZoneList<Expression*>* args = expr->arguments();
4425 int arg_count = args->length(); 4422 int arg_count = args->length();
4426 4423
4427 SetExpressionPosition(expr); 4424 SetExpressionPosition(expr);
4428 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4425 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
4429 __ Peek(x1, (arg_count + 1) * kPointerSize); 4426 __ Peek(x1, (arg_count + 1) * kPointerSize);
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
5193 __ Drop(1); // The function is still on the stack; drop it. 5190 __ Drop(1); // The function is still on the stack; drop it.
5194 5191
5195 // if (!result.done) goto l_try; 5192 // if (!result.done) goto l_try;
5196 __ Bind(&l_loop); 5193 __ Bind(&l_loop);
5197 __ Move(load_receiver, x0); 5194 __ Move(load_receiver, x0);
5198 5195
5199 __ Push(load_receiver); // save result 5196 __ Push(load_receiver); // save result
5200 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" 5197 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
5201 __ Mov(LoadDescriptor::SlotRegister(), 5198 __ Mov(LoadDescriptor::SlotRegister(),
5202 SmiFromSlot(expr->DoneFeedbackSlot())); 5199 SmiFromSlot(expr->DoneFeedbackSlot()));
5203 CallLoadIC(NOT_CONTEXTUAL); // x0=result.done 5200 CallLoadIC(INSIDE_TYPEOF); // x0=result.done
5204 // The ToBooleanStub argument (result.done) is in x0. 5201 // The ToBooleanStub argument (result.done) is in x0.
5205 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 5202 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
5206 CallIC(bool_ic); 5203 CallIC(bool_ic);
5207 __ Cbz(x0, &l_try); 5204 __ Cbz(x0, &l_try);
5208 5205
5209 // result.value 5206 // result.value
5210 __ Pop(load_receiver); // result 5207 __ Pop(load_receiver); // result
5211 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" 5208 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
5212 __ Mov(LoadDescriptor::SlotRegister(), 5209 __ Mov(LoadDescriptor::SlotRegister(),
5213 SmiFromSlot(expr->ValueFeedbackSlot())); 5210 SmiFromSlot(expr->ValueFeedbackSlot()));
5214 CallLoadIC(NOT_CONTEXTUAL); // x0=result.value 5211 CallLoadIC(INSIDE_TYPEOF); // x0=result.value
5215 context()->DropAndPlug(2, x0); // drop iter and g 5212 context()->DropAndPlug(2, x0); // drop iter and g
5216 break; 5213 break;
5217 } 5214 }
5218 } 5215 }
5219 } 5216 }
5220 5217
5221 5218
5222 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 5219 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
5223 Expression *value, 5220 Expression *value,
5224 JSGeneratorObject::ResumeMode resume_mode) { 5221 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
5569 } 5566 }
5570 5567
5571 return INTERRUPT; 5568 return INTERRUPT;
5572 } 5569 }
5573 5570
5574 5571
5575 } // namespace internal 5572 } // namespace internal
5576 } // namespace v8 5573 } // namespace v8
5577 5574
5578 #endif // V8_TARGET_ARCH_ARM64 5575 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/arm64/lithium-arm64.h » ('j') | src/ic/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698