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

Side by Side Diff: src/mips/full-codegen-mips.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_MIPS 7 #if V8_TARGET_ARCH_MIPS
8 8
9 // Note on Mips implementation: 9 // Note on Mips implementation:
10 // 10 //
(...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 Operand(isolate()->factory()->home_object_symbol())); 1357 Operand(isolate()->factory()->home_object_symbol()));
1358 __ lw(StoreDescriptor::ValueRegister(), 1358 __ lw(StoreDescriptor::ValueRegister(),
1359 MemOperand(sp, offset * kPointerSize)); 1359 MemOperand(sp, offset * kPointerSize));
1360 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); 1360 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1361 CallStoreIC(); 1361 CallStoreIC();
1362 } 1362 }
1363 } 1363 }
1364 1364
1365 1365
1366 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1366 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1367 TypeofState typeof_state, 1367 TypeofMode typeof_mode,
1368 Label* slow) { 1368 Label* slow) {
1369 Register current = cp; 1369 Register current = cp;
1370 Register next = a1; 1370 Register next = a1;
1371 Register temp = a2; 1371 Register temp = a2;
1372 1372
1373 Scope* s = scope(); 1373 Scope* s = scope();
1374 while (s != NULL) { 1374 while (s != NULL) {
1375 if (s->num_heap_slots() > 0) { 1375 if (s->num_heap_slots() > 0) {
1376 if (s->calls_sloppy_eval()) { 1376 if (s->calls_sloppy_eval()) {
1377 // Check that extension is NULL. 1377 // Check that extension is NULL.
(...skipping 25 matching lines...) Expand all
1403 __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX)); 1403 __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX));
1404 __ Branch(slow, ne, temp, Operand(zero_reg)); 1404 __ Branch(slow, ne, temp, Operand(zero_reg));
1405 // Load next context in chain. 1405 // Load next context in chain.
1406 __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX)); 1406 __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX));
1407 __ Branch(&loop); 1407 __ Branch(&loop);
1408 __ bind(&fast); 1408 __ bind(&fast);
1409 } 1409 }
1410 1410
1411 // All extension objects were empty and it is safe to use a normal global 1411 // All extension objects were empty and it is safe to use a normal global
1412 // load machinery. 1412 // load machinery.
1413 EmitGlobalVariableLoad(proxy, typeof_state); 1413 EmitGlobalVariableLoad(proxy, typeof_mode);
1414 } 1414 }
1415 1415
1416 1416
1417 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1417 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1418 Label* slow) { 1418 Label* slow) {
1419 DCHECK(var->IsContextSlot()); 1419 DCHECK(var->IsContextSlot());
1420 Register context = cp; 1420 Register context = cp;
1421 Register next = a3; 1421 Register next = a3;
1422 Register temp = t0; 1422 Register temp = t0;
1423 1423
(...skipping 14 matching lines...) Expand all
1438 __ Branch(slow, ne, temp, Operand(zero_reg)); 1438 __ Branch(slow, ne, temp, Operand(zero_reg));
1439 1439
1440 // This function is used only for loads, not stores, so it's safe to 1440 // This function is used only for loads, not stores, so it's safe to
1441 // return an cp-based operand (the write barrier cannot be allowed to 1441 // return an cp-based operand (the write barrier cannot be allowed to
1442 // destroy the cp register). 1442 // destroy the cp register).
1443 return ContextOperand(context, var->index()); 1443 return ContextOperand(context, var->index());
1444 } 1444 }
1445 1445
1446 1446
1447 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, 1447 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1448 TypeofState typeof_state, 1448 TypeofMode typeof_mode,
1449 Label* slow, 1449 Label* slow, Label* done) {
1450 Label* done) {
1451 // Generate fast-case code for variables that might be shadowed by 1450 // Generate fast-case code for variables that might be shadowed by
1452 // eval-introduced variables. Eval is used a lot without 1451 // eval-introduced variables. Eval is used a lot without
1453 // introducing variables. In those cases, we do not want to 1452 // introducing variables. In those cases, we do not want to
1454 // perform a runtime call for all variables in the scope 1453 // perform a runtime call for all variables in the scope
1455 // containing the eval. 1454 // containing the eval.
1456 Variable* var = proxy->var(); 1455 Variable* var = proxy->var();
1457 if (var->mode() == DYNAMIC_GLOBAL) { 1456 if (var->mode() == DYNAMIC_GLOBAL) {
1458 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); 1457 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1459 __ Branch(done); 1458 __ Branch(done);
1460 } else if (var->mode() == DYNAMIC_LOCAL) { 1459 } else if (var->mode() == DYNAMIC_LOCAL) {
1461 Variable* local = var->local_if_not_shadowed(); 1460 Variable* local = var->local_if_not_shadowed();
1462 __ lw(v0, ContextSlotOperandCheckExtensions(local, slow)); 1461 __ lw(v0, ContextSlotOperandCheckExtensions(local, slow));
1463 if (local->mode() == LET || local->mode() == CONST || 1462 if (local->mode() == LET || local->mode() == CONST ||
1464 local->mode() == CONST_LEGACY) { 1463 local->mode() == CONST_LEGACY) {
1465 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1464 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1466 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. 1465 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1467 if (local->mode() == CONST_LEGACY) { 1466 if (local->mode() == CONST_LEGACY) {
1468 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1467 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1469 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole. 1468 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole.
1470 } else { // LET || CONST 1469 } else { // LET || CONST
1471 __ Branch(done, ne, at, Operand(zero_reg)); 1470 __ Branch(done, ne, at, Operand(zero_reg));
1472 __ li(a0, Operand(var->name())); 1471 __ li(a0, Operand(var->name()));
1473 __ push(a0); 1472 __ push(a0);
1474 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1473 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1475 } 1474 }
1476 } 1475 }
1477 __ Branch(done); 1476 __ Branch(done);
1478 } 1477 }
1479 } 1478 }
1480 1479
1481 1480
1482 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1481 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1483 TypeofState typeof_state) { 1482 TypeofMode typeof_mode) {
1484 Variable* var = proxy->var(); 1483 Variable* var = proxy->var();
1485 DCHECK(var->IsUnallocatedOrGlobalSlot() || 1484 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1486 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); 1485 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1487 __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1486 __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1488 __ li(LoadDescriptor::NameRegister(), Operand(var->name())); 1487 __ li(LoadDescriptor::NameRegister(), Operand(var->name()));
1489 __ li(LoadDescriptor::SlotRegister(), 1488 __ li(LoadDescriptor::SlotRegister(),
1490 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1489 Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
1491 // Inside typeof use a regular load, not a contextual load, to avoid 1490 CallLoadIC(typeof_mode);
1492 // a reference error.
1493 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
1494 } 1491 }
1495 1492
1496 1493
1497 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1494 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1498 TypeofState typeof_state) { 1495 TypeofMode typeof_mode) {
1499 // Record position before possible IC call. 1496 // Record position before possible IC call.
1500 SetExpressionPosition(proxy); 1497 SetExpressionPosition(proxy);
1501 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1498 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1502 Variable* var = proxy->var(); 1499 Variable* var = proxy->var();
1503 1500
1504 // Three cases: global variables, lookup variables, and all other types of 1501 // Three cases: global variables, lookup variables, and all other types of
1505 // variables. 1502 // variables.
1506 switch (var->location()) { 1503 switch (var->location()) {
1507 case VariableLocation::GLOBAL: 1504 case VariableLocation::GLOBAL:
1508 case VariableLocation::UNALLOCATED: { 1505 case VariableLocation::UNALLOCATED: {
1509 Comment cmnt(masm_, "[ Global variable"); 1506 Comment cmnt(masm_, "[ Global variable");
1510 EmitGlobalVariableLoad(proxy, typeof_state); 1507 EmitGlobalVariableLoad(proxy, typeof_mode);
1511 context()->Plug(v0); 1508 context()->Plug(v0);
1512 break; 1509 break;
1513 } 1510 }
1514 1511
1515 case VariableLocation::PARAMETER: 1512 case VariableLocation::PARAMETER:
1516 case VariableLocation::LOCAL: 1513 case VariableLocation::LOCAL:
1517 case VariableLocation::CONTEXT: { 1514 case VariableLocation::CONTEXT: {
1518 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); 1515 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1519 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1516 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1520 : "[ Stack variable"); 1517 : "[ Stack variable");
1521 if (var->binding_needs_init()) { 1518 if (var->binding_needs_init()) {
1522 // var->scope() may be NULL when the proxy is located in eval code and 1519 // var->scope() may be NULL when the proxy is located in eval code and
1523 // refers to a potential outside binding. Currently those bindings are 1520 // refers to a potential outside binding. Currently those bindings are
1524 // always looked up dynamically, i.e. in that case 1521 // always looked up dynamically, i.e. in that case
1525 // var->location() == LOOKUP. 1522 // var->location() == LOOKUP.
1526 // always holds. 1523 // always holds.
1527 DCHECK(var->scope() != NULL); 1524 DCHECK(var->scope() != NULL);
1528 1525
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 } 1581 }
1585 context()->Plug(var); 1582 context()->Plug(var);
1586 break; 1583 break;
1587 } 1584 }
1588 1585
1589 case VariableLocation::LOOKUP: { 1586 case VariableLocation::LOOKUP: {
1590 Comment cmnt(masm_, "[ Lookup variable"); 1587 Comment cmnt(masm_, "[ Lookup variable");
1591 Label done, slow; 1588 Label done, slow;
1592 // Generate code for loading from variables potentially shadowed 1589 // Generate code for loading from variables potentially shadowed
1593 // by eval-introduced variables. 1590 // by eval-introduced variables.
1594 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); 1591 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1595 __ bind(&slow); 1592 __ bind(&slow);
1596 __ li(a1, Operand(var->name())); 1593 __ li(a1, Operand(var->name()));
1597 __ Push(cp, a1); // Context and name. 1594 __ Push(cp, a1); // Context and name.
1598 Runtime::FunctionId function_id = 1595 Runtime::FunctionId function_id =
1599 typeof_state == NOT_INSIDE_TYPEOF 1596 typeof_mode == NOT_INSIDE_TYPEOF
1600 ? Runtime::kLoadLookupSlot 1597 ? Runtime::kLoadLookupSlot
1601 : Runtime::kLoadLookupSlotNoReferenceError; 1598 : Runtime::kLoadLookupSlotNoReferenceError;
1602 __ CallRuntime(function_id, 2); 1599 __ CallRuntime(function_id, 2);
1603 __ bind(&done); 1600 __ bind(&done);
1604 context()->Plug(v0); 1601 context()->Plug(v0);
1605 } 1602 }
1606 } 1603 }
1607 } 1604 }
1608 1605
1609 1606
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2269 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2273 __ Drop(1); // The function is still on the stack; drop it. 2270 __ Drop(1); // The function is still on the stack; drop it.
2274 2271
2275 // if (!result.done) goto l_try; 2272 // if (!result.done) goto l_try;
2276 __ Move(load_receiver, v0); 2273 __ Move(load_receiver, v0);
2277 2274
2278 __ push(load_receiver); // save result 2275 __ push(load_receiver); // save result
2279 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" 2276 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
2280 __ li(LoadDescriptor::SlotRegister(), 2277 __ li(LoadDescriptor::SlotRegister(),
2281 Operand(SmiFromSlot(expr->DoneFeedbackSlot()))); 2278 Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
2282 CallLoadIC(NOT_CONTEXTUAL); // v0=result.done 2279 CallLoadIC(INSIDE_TYPEOF); // v0=result.done
2283 __ mov(a0, v0); 2280 __ mov(a0, v0);
2284 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2281 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2285 CallIC(bool_ic); 2282 CallIC(bool_ic);
2286 __ Branch(&l_try, eq, v0, Operand(zero_reg)); 2283 __ Branch(&l_try, eq, v0, Operand(zero_reg));
2287 2284
2288 // result.value 2285 // result.value
2289 __ pop(load_receiver); // result 2286 __ pop(load_receiver); // result
2290 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" 2287 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
2291 __ li(LoadDescriptor::SlotRegister(), 2288 __ li(LoadDescriptor::SlotRegister(),
2292 Operand(SmiFromSlot(expr->ValueFeedbackSlot()))); 2289 Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
2293 CallLoadIC(NOT_CONTEXTUAL); // v0=result.value 2290 CallLoadIC(INSIDE_TYPEOF); // v0=result.value
2294 context()->DropAndPlug(2, v0); // drop iter and g 2291 context()->DropAndPlug(2, v0); // drop iter and g
2295 break; 2292 break;
2296 } 2293 }
2297 } 2294 }
2298 } 2295 }
2299 2296
2300 2297
2301 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2298 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2302 Expression *value, 2299 Expression *value,
2303 JSGeneratorObject::ResumeMode resume_mode) { 2300 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2425 2422
2426 2423
2427 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2424 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2428 SetExpressionPosition(prop); 2425 SetExpressionPosition(prop);
2429 Literal* key = prop->key()->AsLiteral(); 2426 Literal* key = prop->key()->AsLiteral();
2430 DCHECK(!prop->IsSuperAccess()); 2427 DCHECK(!prop->IsSuperAccess());
2431 2428
2432 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); 2429 __ li(LoadDescriptor::NameRegister(), Operand(key->value()));
2433 __ li(LoadDescriptor::SlotRegister(), 2430 __ li(LoadDescriptor::SlotRegister(),
2434 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2431 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2435 CallLoadIC(NOT_CONTEXTUAL, language_mode()); 2432 CallLoadIC(INSIDE_TYPEOF, language_mode());
2436 } 2433 }
2437 2434
2438 2435
2439 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2436 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2440 // Stack: receiver, home_object. 2437 // Stack: receiver, home_object.
2441 SetExpressionPosition(prop); 2438 SetExpressionPosition(prop);
2442 2439
2443 Literal* key = prop->key()->AsLiteral(); 2440 Literal* key = prop->key()->AsLiteral();
2444 DCHECK(!key->value()->IsSmi()); 2441 DCHECK(!key->value()->IsSmi());
2445 DCHECK(prop->IsSuperAccess()); 2442 DCHECK(prop->IsSuperAccess());
(...skipping 2290 matching lines...) Expand 10 before | Expand all | Expand 10 after
4736 // Push the builtins object as the receiver. 4733 // Push the builtins object as the receiver.
4737 Register receiver = LoadDescriptor::ReceiverRegister(); 4734 Register receiver = LoadDescriptor::ReceiverRegister();
4738 __ lw(receiver, GlobalObjectOperand()); 4735 __ lw(receiver, GlobalObjectOperand());
4739 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); 4736 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
4740 __ push(receiver); 4737 __ push(receiver);
4741 4738
4742 // Load the function from the receiver. 4739 // Load the function from the receiver.
4743 __ li(LoadDescriptor::NameRegister(), Operand(expr->name())); 4740 __ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
4744 __ li(LoadDescriptor::SlotRegister(), 4741 __ li(LoadDescriptor::SlotRegister(),
4745 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); 4742 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
4746 CallLoadIC(NOT_CONTEXTUAL); 4743 CallLoadIC(INSIDE_TYPEOF);
4747 } 4744 }
4748 4745
4749 4746
4750 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 4747 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
4751 ZoneList<Expression*>* args = expr->arguments(); 4748 ZoneList<Expression*>* args = expr->arguments();
4752 int arg_count = args->length(); 4749 int arg_count = args->length();
4753 4750
4754 SetExpressionPosition(expr); 4751 SetExpressionPosition(expr);
4755 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4752 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
4756 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 4753 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
5550 reinterpret_cast<uint32_t>( 5547 reinterpret_cast<uint32_t>(
5551 isolate->builtins()->OsrAfterStackCheck()->entry())); 5548 isolate->builtins()->OsrAfterStackCheck()->entry()));
5552 return OSR_AFTER_STACK_CHECK; 5549 return OSR_AFTER_STACK_CHECK;
5553 } 5550 }
5554 5551
5555 5552
5556 } // namespace internal 5553 } // namespace internal
5557 } // namespace v8 5554 } // namespace v8
5558 5555
5559 #endif // V8_TARGET_ARCH_MIPS 5556 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« src/ic/ic.cc ('K') | « src/mips/codegen-mips.h ('k') | src/mips/lithium-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698