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

Side by Side Diff: src/arm/full-codegen-arm.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_ARM 7 #if V8_TARGET_ARCH_ARM
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 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 Operand(isolate()->factory()->home_object_symbol())); 1362 Operand(isolate()->factory()->home_object_symbol()));
1363 __ ldr(StoreDescriptor::ValueRegister(), 1363 __ ldr(StoreDescriptor::ValueRegister(),
1364 MemOperand(sp, offset * kPointerSize)); 1364 MemOperand(sp, offset * kPointerSize));
1365 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); 1365 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1366 CallStoreIC(); 1366 CallStoreIC();
1367 } 1367 }
1368 } 1368 }
1369 1369
1370 1370
1371 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1371 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1372 TypeofState typeof_state, 1372 TypeofMode typeof_mode,
1373 Label* slow) { 1373 Label* slow) {
1374 Register current = cp; 1374 Register current = cp;
1375 Register next = r1; 1375 Register next = r1;
1376 Register temp = r2; 1376 Register temp = r2;
1377 1377
1378 Scope* s = scope(); 1378 Scope* s = scope();
1379 while (s != NULL) { 1379 while (s != NULL) {
1380 if (s->num_heap_slots() > 0) { 1380 if (s->num_heap_slots() > 0) {
1381 if (s->calls_sloppy_eval()) { 1381 if (s->calls_sloppy_eval()) {
1382 // Check that extension is NULL. 1382 // Check that extension is NULL.
(...skipping 28 matching lines...) Expand all
1411 __ tst(temp, temp); 1411 __ tst(temp, temp);
1412 __ b(ne, slow); 1412 __ b(ne, slow);
1413 // Load next context in chain. 1413 // Load next context in chain.
1414 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); 1414 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX));
1415 __ b(&loop); 1415 __ b(&loop);
1416 __ bind(&fast); 1416 __ bind(&fast);
1417 } 1417 }
1418 1418
1419 // All extension objects were empty and it is safe to use a normal global 1419 // All extension objects were empty and it is safe to use a normal global
1420 // load machinery. 1420 // load machinery.
1421 EmitGlobalVariableLoad(proxy, typeof_state); 1421 EmitGlobalVariableLoad(proxy, typeof_mode);
1422 } 1422 }
1423 1423
1424 1424
1425 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1425 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1426 Label* slow) { 1426 Label* slow) {
1427 DCHECK(var->IsContextSlot()); 1427 DCHECK(var->IsContextSlot());
1428 Register context = cp; 1428 Register context = cp;
1429 Register next = r3; 1429 Register next = r3;
1430 Register temp = r4; 1430 Register temp = r4;
1431 1431
(...skipping 16 matching lines...) Expand all
1448 __ b(ne, slow); 1448 __ b(ne, slow);
1449 1449
1450 // This function is used only for loads, not stores, so it's safe to 1450 // This function is used only for loads, not stores, so it's safe to
1451 // return an cp-based operand (the write barrier cannot be allowed to 1451 // return an cp-based operand (the write barrier cannot be allowed to
1452 // destroy the cp register). 1452 // destroy the cp register).
1453 return ContextOperand(context, var->index()); 1453 return ContextOperand(context, var->index());
1454 } 1454 }
1455 1455
1456 1456
1457 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, 1457 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1458 TypeofState typeof_state, 1458 TypeofMode typeof_mode,
1459 Label* slow, 1459 Label* slow, Label* done) {
1460 Label* done) {
1461 // Generate fast-case code for variables that might be shadowed by 1460 // Generate fast-case code for variables that might be shadowed by
1462 // eval-introduced variables. Eval is used a lot without 1461 // eval-introduced variables. Eval is used a lot without
1463 // introducing variables. In those cases, we do not want to 1462 // introducing variables. In those cases, we do not want to
1464 // perform a runtime call for all variables in the scope 1463 // perform a runtime call for all variables in the scope
1465 // containing the eval. 1464 // containing the eval.
1466 Variable* var = proxy->var(); 1465 Variable* var = proxy->var();
1467 if (var->mode() == DYNAMIC_GLOBAL) { 1466 if (var->mode() == DYNAMIC_GLOBAL) {
1468 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); 1467 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1469 __ jmp(done); 1468 __ jmp(done);
1470 } else if (var->mode() == DYNAMIC_LOCAL) { 1469 } else if (var->mode() == DYNAMIC_LOCAL) {
1471 Variable* local = var->local_if_not_shadowed(); 1470 Variable* local = var->local_if_not_shadowed();
1472 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); 1471 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow));
1473 if (local->mode() == LET || local->mode() == CONST || 1472 if (local->mode() == LET || local->mode() == CONST ||
1474 local->mode() == CONST_LEGACY) { 1473 local->mode() == CONST_LEGACY) {
1475 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); 1474 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
1476 if (local->mode() == CONST_LEGACY) { 1475 if (local->mode() == CONST_LEGACY) {
1477 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 1476 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1478 } else { // LET || CONST 1477 } else { // LET || CONST
1479 __ b(ne, done); 1478 __ b(ne, done);
1480 __ mov(r0, Operand(var->name())); 1479 __ mov(r0, Operand(var->name()));
1481 __ push(r0); 1480 __ push(r0);
1482 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1481 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1483 } 1482 }
1484 } 1483 }
1485 __ jmp(done); 1484 __ jmp(done);
1486 } 1485 }
1487 } 1486 }
1488 1487
1489 1488
1490 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1489 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1491 TypeofState typeof_state) { 1490 TypeofMode typeof_mode) {
1492 Variable* var = proxy->var(); 1491 Variable* var = proxy->var();
1493 DCHECK(var->IsUnallocatedOrGlobalSlot() || 1492 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1494 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); 1493 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1495 __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1494 __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1496 __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); 1495 __ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
1497 __ mov(LoadDescriptor::SlotRegister(), 1496 __ mov(LoadDescriptor::SlotRegister(),
1498 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1497 Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
1499 // Inside typeof use a regular load, not a contextual load, to avoid 1498 CallLoadIC(typeof_mode);
1500 // a reference error.
1501 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
1502 } 1499 }
1503 1500
1504 1501
1505 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1502 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1506 TypeofState typeof_state) { 1503 TypeofMode typeof_mode) {
1507 // Record position before possible IC call. 1504 // Record position before possible IC call.
1508 SetExpressionPosition(proxy); 1505 SetExpressionPosition(proxy);
1509 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1506 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1510 Variable* var = proxy->var(); 1507 Variable* var = proxy->var();
1511 1508
1512 // Three cases: global variables, lookup variables, and all other types of 1509 // Three cases: global variables, lookup variables, and all other types of
1513 // variables. 1510 // variables.
1514 switch (var->location()) { 1511 switch (var->location()) {
1515 case VariableLocation::GLOBAL: 1512 case VariableLocation::GLOBAL:
1516 case VariableLocation::UNALLOCATED: { 1513 case VariableLocation::UNALLOCATED: {
1517 Comment cmnt(masm_, "[ Global variable"); 1514 Comment cmnt(masm_, "[ Global variable");
1518 EmitGlobalVariableLoad(proxy, typeof_state); 1515 EmitGlobalVariableLoad(proxy, typeof_mode);
1519 context()->Plug(r0); 1516 context()->Plug(r0);
1520 break; 1517 break;
1521 } 1518 }
1522 1519
1523 case VariableLocation::PARAMETER: 1520 case VariableLocation::PARAMETER:
1524 case VariableLocation::LOCAL: 1521 case VariableLocation::LOCAL:
1525 case VariableLocation::CONTEXT: { 1522 case VariableLocation::CONTEXT: {
1526 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); 1523 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1527 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1524 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1528 : "[ Stack variable"); 1525 : "[ Stack variable");
1529 if (var->binding_needs_init()) { 1526 if (var->binding_needs_init()) {
1530 // var->scope() may be NULL when the proxy is located in eval code and 1527 // var->scope() may be NULL when the proxy is located in eval code and
1531 // refers to a potential outside binding. Currently those bindings are 1528 // refers to a potential outside binding. Currently those bindings are
1532 // always looked up dynamically, i.e. in that case 1529 // always looked up dynamically, i.e. in that case
1533 // var->location() == LOOKUP. 1530 // var->location() == LOOKUP.
1534 // always holds. 1531 // always holds.
1535 DCHECK(var->scope() != NULL); 1532 DCHECK(var->scope() != NULL);
1536 1533
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 } 1587 }
1591 context()->Plug(var); 1588 context()->Plug(var);
1592 break; 1589 break;
1593 } 1590 }
1594 1591
1595 case VariableLocation::LOOKUP: { 1592 case VariableLocation::LOOKUP: {
1596 Comment cmnt(masm_, "[ Lookup variable"); 1593 Comment cmnt(masm_, "[ Lookup variable");
1597 Label done, slow; 1594 Label done, slow;
1598 // Generate code for loading from variables potentially shadowed 1595 // Generate code for loading from variables potentially shadowed
1599 // by eval-introduced variables. 1596 // by eval-introduced variables.
1600 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); 1597 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1601 __ bind(&slow); 1598 __ bind(&slow);
1602 __ mov(r1, Operand(var->name())); 1599 __ mov(r1, Operand(var->name()));
1603 __ Push(cp, r1); // Context and name. 1600 __ Push(cp, r1); // Context and name.
1604 Runtime::FunctionId function_id = 1601 Runtime::FunctionId function_id =
1605 typeof_state == NOT_INSIDE_TYPEOF 1602 typeof_mode == NOT_INSIDE_TYPEOF
1606 ? Runtime::kLoadLookupSlot 1603 ? Runtime::kLoadLookupSlot
1607 : Runtime::kLoadLookupSlotNoReferenceError; 1604 : Runtime::kLoadLookupSlotNoReferenceError;
1608 __ CallRuntime(function_id, 2); 1605 __ CallRuntime(function_id, 2);
1609 __ bind(&done); 1606 __ bind(&done);
1610 context()->Plug(r0); 1607 context()->Plug(r0);
1611 } 1608 }
1612 } 1609 }
1613 } 1610 }
1614 1611
1615 1612
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 __ Drop(1); // The function is still on the stack; drop it. 2273 __ Drop(1); // The function is still on the stack; drop it.
2277 2274
2278 // if (!result.done) goto l_try; 2275 // if (!result.done) goto l_try;
2279 __ bind(&l_loop); 2276 __ bind(&l_loop);
2280 __ Move(load_receiver, r0); 2277 __ Move(load_receiver, r0);
2281 2278
2282 __ push(load_receiver); // save result 2279 __ push(load_receiver); // save result
2283 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" 2280 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
2284 __ mov(LoadDescriptor::SlotRegister(), 2281 __ mov(LoadDescriptor::SlotRegister(),
2285 Operand(SmiFromSlot(expr->DoneFeedbackSlot()))); 2282 Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
2286 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done 2283 CallLoadIC(INSIDE_TYPEOF); // r0=result.done
2287 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2284 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2288 CallIC(bool_ic); 2285 CallIC(bool_ic);
2289 __ cmp(r0, Operand(0)); 2286 __ cmp(r0, Operand(0));
2290 __ b(eq, &l_try); 2287 __ b(eq, &l_try);
2291 2288
2292 // result.value 2289 // result.value
2293 __ pop(load_receiver); // result 2290 __ pop(load_receiver); // result
2294 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" 2291 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
2295 __ mov(LoadDescriptor::SlotRegister(), 2292 __ mov(LoadDescriptor::SlotRegister(),
2296 Operand(SmiFromSlot(expr->ValueFeedbackSlot()))); 2293 Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
2297 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value 2294 CallLoadIC(INSIDE_TYPEOF); // r0=result.value
2298 context()->DropAndPlug(2, r0); // drop iter and g 2295 context()->DropAndPlug(2, r0); // drop iter and g
2299 break; 2296 break;
2300 } 2297 }
2301 } 2298 }
2302 } 2299 }
2303 2300
2304 2301
2305 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2302 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2306 Expression *value, 2303 Expression *value,
2307 JSGeneratorObject::ResumeMode resume_mode) { 2304 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2439 2436
2440 2437
2441 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2438 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2442 SetExpressionPosition(prop); 2439 SetExpressionPosition(prop);
2443 Literal* key = prop->key()->AsLiteral(); 2440 Literal* key = prop->key()->AsLiteral();
2444 DCHECK(!prop->IsSuperAccess()); 2441 DCHECK(!prop->IsSuperAccess());
2445 2442
2446 __ mov(LoadDescriptor::NameRegister(), Operand(key->value())); 2443 __ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
2447 __ mov(LoadDescriptor::SlotRegister(), 2444 __ mov(LoadDescriptor::SlotRegister(),
2448 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2445 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2449 CallLoadIC(NOT_CONTEXTUAL, language_mode()); 2446 CallLoadIC(INSIDE_TYPEOF, language_mode());
2450 } 2447 }
2451 2448
2452 2449
2453 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2450 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2454 // Stack: receiver, home_object. 2451 // Stack: receiver, home_object.
2455 SetExpressionPosition(prop); 2452 SetExpressionPosition(prop);
2456 Literal* key = prop->key()->AsLiteral(); 2453 Literal* key = prop->key()->AsLiteral();
2457 DCHECK(!key->value()->IsSmi()); 2454 DCHECK(!key->value()->IsSmi());
2458 DCHECK(prop->IsSuperAccess()); 2455 DCHECK(prop->IsSuperAccess());
2459 2456
(...skipping 2257 matching lines...) Expand 10 before | Expand all | Expand 10 after
4717 // Push the builtins object as the receiver. 4714 // Push the builtins object as the receiver.
4718 Register receiver = LoadDescriptor::ReceiverRegister(); 4715 Register receiver = LoadDescriptor::ReceiverRegister();
4719 __ ldr(receiver, GlobalObjectOperand()); 4716 __ ldr(receiver, GlobalObjectOperand());
4720 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); 4717 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
4721 __ push(receiver); 4718 __ push(receiver);
4722 4719
4723 // Load the function from the receiver. 4720 // Load the function from the receiver.
4724 __ mov(LoadDescriptor::NameRegister(), Operand(expr->name())); 4721 __ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
4725 __ mov(LoadDescriptor::SlotRegister(), 4722 __ mov(LoadDescriptor::SlotRegister(),
4726 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); 4723 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
4727 CallLoadIC(NOT_CONTEXTUAL); 4724 CallLoadIC(INSIDE_TYPEOF);
4728 } 4725 }
4729 4726
4730 4727
4731 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 4728 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
4732 ZoneList<Expression*>* args = expr->arguments(); 4729 ZoneList<Expression*>* args = expr->arguments();
4733 int arg_count = args->length(); 4730 int arg_count = args->length();
4734 4731
4735 SetExpressionPosition(expr); 4732 SetExpressionPosition(expr);
4736 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4733 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
4737 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 4734 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after
5591 DCHECK(interrupt_address == 5588 DCHECK(interrupt_address ==
5592 isolate->builtins()->OsrAfterStackCheck()->entry()); 5589 isolate->builtins()->OsrAfterStackCheck()->entry());
5593 return OSR_AFTER_STACK_CHECK; 5590 return OSR_AFTER_STACK_CHECK;
5594 } 5591 }
5595 5592
5596 5593
5597 } // namespace internal 5594 } // namespace internal
5598 } // namespace v8 5595 } // namespace v8
5599 5596
5600 #endif // V8_TARGET_ARCH_ARM 5597 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/lithium-arm.h » ('j') | src/ic/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698