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

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

Issue 195693002: MIPS: Eliminate extended mode, and other modes clean-up (Closed) Base URL: https://github.com/v8/v8.git@gbl
Patch Set: Created 6 years, 9 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/mips/code-stubs-mips.cc ('k') | src/mips/ic-mips.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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 #ifdef DEBUG 149 #ifdef DEBUG
150 if (strlen(FLAG_stop_at) > 0 && 150 if (strlen(FLAG_stop_at) > 0 &&
151 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 151 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
152 __ stop("stop-at"); 152 __ stop("stop-at");
153 } 153 }
154 #endif 154 #endif
155 155
156 // Sloppy mode functions and builtins need to replace the receiver with the 156 // Sloppy mode functions and builtins need to replace the receiver with the
157 // global proxy when called as functions (without an explicit receiver 157 // global proxy when called as functions (without an explicit receiver
158 // object). 158 // object).
159 if (info->is_sloppy_mode() && !info->is_native()) { 159 if (info->strict_mode() == SLOPPY && !info->is_native()) {
160 Label ok; 160 Label ok;
161 int receiver_offset = info->scope()->num_parameters() * kPointerSize; 161 int receiver_offset = info->scope()->num_parameters() * kPointerSize;
162 __ lw(at, MemOperand(sp, receiver_offset)); 162 __ lw(at, MemOperand(sp, receiver_offset));
163 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 163 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
164 __ Branch(&ok, ne, a2, Operand(at)); 164 __ Branch(&ok, ne, a2, Operand(at));
165 165
166 __ lw(a2, GlobalObjectOperand()); 166 __ lw(a2, GlobalObjectOperand());
167 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); 167 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
168 168
169 __ sw(a2, MemOperand(sp, receiver_offset)); 169 __ sw(a2, MemOperand(sp, receiver_offset));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 __ Addu(a2, fp, 264 __ Addu(a2, fp,
265 Operand(StandardFrameConstants::kCallerSPOffset + offset)); 265 Operand(StandardFrameConstants::kCallerSPOffset + offset));
266 __ li(a1, Operand(Smi::FromInt(num_parameters))); 266 __ li(a1, Operand(Smi::FromInt(num_parameters)));
267 __ Push(a3, a2, a1); 267 __ Push(a3, a2, a1);
268 268
269 // Arguments to ArgumentsAccessStub: 269 // Arguments to ArgumentsAccessStub:
270 // function, receiver address, parameter count. 270 // function, receiver address, parameter count.
271 // The stub will rewrite receiever and parameter count if the previous 271 // The stub will rewrite receiever and parameter count if the previous
272 // stack frame was an arguments adapter frame. 272 // stack frame was an arguments adapter frame.
273 ArgumentsAccessStub::Type type; 273 ArgumentsAccessStub::Type type;
274 if (!is_sloppy_mode()) { 274 if (strict_mode() == STRICT) {
275 type = ArgumentsAccessStub::NEW_STRICT; 275 type = ArgumentsAccessStub::NEW_STRICT;
276 } else if (function()->has_duplicate_parameters()) { 276 } else if (function()->has_duplicate_parameters()) {
277 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; 277 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
278 } else { 278 } else {
279 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; 279 type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
280 } 280 }
281 ArgumentsAccessStub stub(type); 281 ArgumentsAccessStub stub(type);
282 __ CallStub(&stub); 282 __ CallStub(&stub);
283 283
284 SetVar(arguments, v0, a1, a2); 284 SetVar(arguments, v0, a1, a2);
(...skipping 10 matching lines...) Expand all
295 scope()->VisitIllegalRedeclaration(this); 295 scope()->VisitIllegalRedeclaration(this);
296 296
297 } else { 297 } else {
298 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 298 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
299 { Comment cmnt(masm_, "[ Declarations"); 299 { Comment cmnt(masm_, "[ Declarations");
300 // For named function expressions, declare the function name as a 300 // For named function expressions, declare the function name as a
301 // constant. 301 // constant.
302 if (scope()->is_function_scope() && scope()->function() != NULL) { 302 if (scope()->is_function_scope() && scope()->function() != NULL) {
303 VariableDeclaration* function = scope()->function(); 303 VariableDeclaration* function = scope()->function();
304 ASSERT(function->proxy()->var()->mode() == CONST || 304 ASSERT(function->proxy()->var()->mode() == CONST ||
305 function->proxy()->var()->mode() == CONST_HARMONY); 305 function->proxy()->var()->mode() == CONST_LEGACY);
306 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); 306 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
307 VisitVariableDeclaration(function); 307 VisitVariableDeclaration(function);
308 } 308 }
309 VisitDeclarations(scope()->declarations()); 309 VisitDeclarations(scope()->declarations());
310 } 310 }
311 311
312 { Comment cmnt(masm_, "[ Stack check"); 312 { Comment cmnt(masm_, "[ Stack check");
313 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 313 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
314 Label ok; 314 Label ok;
315 __ LoadRoot(t0, Heap::kStackLimitRootIndex); 315 __ LoadRoot(t0, Heap::kStackLimitRootIndex);
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 796
797 797
798 void FullCodeGenerator::VisitVariableDeclaration( 798 void FullCodeGenerator::VisitVariableDeclaration(
799 VariableDeclaration* declaration) { 799 VariableDeclaration* declaration) {
800 // If it was not possible to allocate the variable at compile time, we 800 // If it was not possible to allocate the variable at compile time, we
801 // need to "declare" it at runtime to make sure it actually exists in the 801 // need to "declare" it at runtime to make sure it actually exists in the
802 // local context. 802 // local context.
803 VariableProxy* proxy = declaration->proxy(); 803 VariableProxy* proxy = declaration->proxy();
804 VariableMode mode = declaration->mode(); 804 VariableMode mode = declaration->mode();
805 Variable* variable = proxy->var(); 805 Variable* variable = proxy->var();
806 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; 806 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
807 switch (variable->location()) { 807 switch (variable->location()) {
808 case Variable::UNALLOCATED: 808 case Variable::UNALLOCATED:
809 globals_->Add(variable->name(), zone()); 809 globals_->Add(variable->name(), zone());
810 globals_->Add(variable->binding_needs_init() 810 globals_->Add(variable->binding_needs_init()
811 ? isolate()->factory()->the_hole_value() 811 ? isolate()->factory()->the_hole_value()
812 : isolate()->factory()->undefined_value(), 812 : isolate()->factory()->undefined_value(),
813 zone()); 813 zone());
814 break; 814 break;
815 815
816 case Variable::PARAMETER: 816 case Variable::PARAMETER:
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 // space for nested functions that don't need literals cloning. If 1329 // space for nested functions that don't need literals cloning. If
1330 // we're running with the --always-opt or the --prepare-always-opt 1330 // we're running with the --always-opt or the --prepare-always-opt
1331 // flag, we need to use the runtime function so that the new function 1331 // flag, we need to use the runtime function so that the new function
1332 // we are creating here gets a chance to have its code optimized and 1332 // we are creating here gets a chance to have its code optimized and
1333 // doesn't just get a copy of the existing unoptimized code. 1333 // doesn't just get a copy of the existing unoptimized code.
1334 if (!FLAG_always_opt && 1334 if (!FLAG_always_opt &&
1335 !FLAG_prepare_always_opt && 1335 !FLAG_prepare_always_opt &&
1336 !pretenure && 1336 !pretenure &&
1337 scope()->is_function_scope() && 1337 scope()->is_function_scope() &&
1338 info->num_literals() == 0) { 1338 info->num_literals() == 0) {
1339 FastNewClosureStub stub(info->language_mode(), info->is_generator()); 1339 FastNewClosureStub stub(info->strict_mode(), info->is_generator());
1340 __ li(a2, Operand(info)); 1340 __ li(a2, Operand(info));
1341 __ CallStub(&stub); 1341 __ CallStub(&stub);
1342 } else { 1342 } else {
1343 __ li(a0, Operand(info)); 1343 __ li(a0, Operand(info));
1344 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex 1344 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex
1345 : Heap::kFalseValueRootIndex); 1345 : Heap::kFalseValueRootIndex);
1346 __ Push(cp, a0, a1); 1346 __ Push(cp, a0, a1);
1347 __ CallRuntime(Runtime::kNewClosure, 3); 1347 __ CallRuntime(Runtime::kNewClosure, 3);
1348 } 1348 }
1349 context()->Plug(v0); 1349 context()->Plug(v0);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 // eval-introduced variables. Eval is used a lot without 1448 // eval-introduced variables. Eval is used a lot without
1449 // introducing variables. In those cases, we do not want to 1449 // introducing variables. In those cases, we do not want to
1450 // perform a runtime call for all variables in the scope 1450 // perform a runtime call for all variables in the scope
1451 // containing the eval. 1451 // containing the eval.
1452 if (var->mode() == DYNAMIC_GLOBAL) { 1452 if (var->mode() == DYNAMIC_GLOBAL) {
1453 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 1453 EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
1454 __ Branch(done); 1454 __ Branch(done);
1455 } else if (var->mode() == DYNAMIC_LOCAL) { 1455 } else if (var->mode() == DYNAMIC_LOCAL) {
1456 Variable* local = var->local_if_not_shadowed(); 1456 Variable* local = var->local_if_not_shadowed();
1457 __ lw(v0, ContextSlotOperandCheckExtensions(local, slow)); 1457 __ lw(v0, ContextSlotOperandCheckExtensions(local, slow));
1458 if (local->mode() == LET || 1458 if (local->mode() == LET || local->mode() == CONST ||
1459 local->mode() == CONST || 1459 local->mode() == CONST_LEGACY) {
1460 local->mode() == CONST_HARMONY) {
1461 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1460 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1462 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. 1461 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1463 if (local->mode() == CONST) { 1462 if (local->mode() == CONST_LEGACY) {
1464 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1463 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1465 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole. 1464 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole.
1466 } else { // LET || CONST_HARMONY 1465 } else { // LET || CONST
1467 __ Branch(done, ne, at, Operand(zero_reg)); 1466 __ Branch(done, ne, at, Operand(zero_reg));
1468 __ li(a0, Operand(var->name())); 1467 __ li(a0, Operand(var->name()));
1469 __ push(a0); 1468 __ push(a0);
1470 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1469 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1471 } 1470 }
1472 } 1471 }
1473 __ Branch(done); 1472 __ Branch(done);
1474 } 1473 }
1475 } 1474 }
1476 1475
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 // binding is initialized: 1522 // binding is initialized:
1524 // function() { f(); let x = 1; function f() { x = 2; } } 1523 // function() { f(); let x = 1; function f() { x = 2; } }
1525 // 1524 //
1526 bool skip_init_check; 1525 bool skip_init_check;
1527 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1526 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
1528 skip_init_check = false; 1527 skip_init_check = false;
1529 } else { 1528 } else {
1530 // Check that we always have valid source position. 1529 // Check that we always have valid source position.
1531 ASSERT(var->initializer_position() != RelocInfo::kNoPosition); 1530 ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
1532 ASSERT(proxy->position() != RelocInfo::kNoPosition); 1531 ASSERT(proxy->position() != RelocInfo::kNoPosition);
1533 skip_init_check = var->mode() != CONST && 1532 skip_init_check = var->mode() != CONST_LEGACY &&
1534 var->initializer_position() < proxy->position(); 1533 var->initializer_position() < proxy->position();
1535 } 1534 }
1536 1535
1537 if (!skip_init_check) { 1536 if (!skip_init_check) {
1538 // Let and const need a read barrier. 1537 // Let and const need a read barrier.
1539 GetVar(v0, var); 1538 GetVar(v0, var);
1540 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1539 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1541 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. 1540 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1542 if (var->mode() == LET || var->mode() == CONST_HARMONY) { 1541 if (var->mode() == LET || var->mode() == CONST) {
1543 // Throw a reference error when using an uninitialized let/const 1542 // Throw a reference error when using an uninitialized let/const
1544 // binding in harmony mode. 1543 // binding in harmony mode.
1545 Label done; 1544 Label done;
1546 __ Branch(&done, ne, at, Operand(zero_reg)); 1545 __ Branch(&done, ne, at, Operand(zero_reg));
1547 __ li(a0, Operand(var->name())); 1546 __ li(a0, Operand(var->name()));
1548 __ push(a0); 1547 __ push(a0);
1549 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1548 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1550 __ bind(&done); 1549 __ bind(&done);
1551 } else { 1550 } else {
1552 // Uninitalized const bindings outside of harmony mode are unholed. 1551 // Uninitalized const bindings outside of harmony mode are unholed.
1553 ASSERT(var->mode() == CONST); 1552 ASSERT(var->mode() == CONST_LEGACY);
1554 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1553 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1555 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole. 1554 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole.
1556 } 1555 }
1557 context()->Plug(v0); 1556 context()->Plug(v0);
1558 break; 1557 break;
1559 } 1558 }
1560 } 1559 }
1561 context()->Plug(var); 1560 context()->Plug(var);
1562 break; 1561 break;
1563 } 1562 }
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after
2452 __ li(a2, Operand(prop->key()->AsLiteral()->value())); 2451 __ li(a2, Operand(prop->key()->AsLiteral()->value()));
2453 CallStoreIC(); 2452 CallStoreIC();
2454 break; 2453 break;
2455 } 2454 }
2456 case KEYED_PROPERTY: { 2455 case KEYED_PROPERTY: {
2457 __ push(result_register()); // Preserve value. 2456 __ push(result_register()); // Preserve value.
2458 VisitForStackValue(prop->obj()); 2457 VisitForStackValue(prop->obj());
2459 VisitForAccumulatorValue(prop->key()); 2458 VisitForAccumulatorValue(prop->key());
2460 __ mov(a1, result_register()); 2459 __ mov(a1, result_register());
2461 __ Pop(a0, a2); // a0 = restored value. 2460 __ Pop(a0, a2); // a0 = restored value.
2462 Handle<Code> ic = is_sloppy_mode() 2461 Handle<Code> ic = strict_mode() == SLOPPY
2463 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2462 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2464 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2463 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2465 CallIC(ic); 2464 CallIC(ic);
2466 break; 2465 break;
2467 } 2466 }
2468 } 2467 }
2469 context()->Plug(v0); 2468 context()->Plug(v0);
2470 } 2469 }
2471 2470
2472 2471
2473 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2472 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2474 Variable* var, MemOperand location) { 2473 Variable* var, MemOperand location) {
2475 __ sw(result_register(), location); 2474 __ sw(result_register(), location);
2476 if (var->IsContextSlot()) { 2475 if (var->IsContextSlot()) {
2477 // RecordWrite may destroy all its register arguments. 2476 // RecordWrite may destroy all its register arguments.
2478 __ Move(a3, result_register()); 2477 __ Move(a3, result_register());
2479 int offset = Context::SlotOffset(var->index()); 2478 int offset = Context::SlotOffset(var->index());
2480 __ RecordWriteContextSlot( 2479 __ RecordWriteContextSlot(
2481 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); 2480 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
2482 } 2481 }
2483 } 2482 }
2484 2483
2485 2484
2486 void FullCodeGenerator::EmitCallStoreContextSlot( 2485 void FullCodeGenerator::EmitCallStoreContextSlot(
2487 Handle<String> name, LanguageMode mode) { 2486 Handle<String> name, StrictMode strict_mode) {
2488 __ li(a1, Operand(name)); 2487 __ li(a1, Operand(name));
2489 __ li(a0, Operand(Smi::FromInt(mode))); 2488 __ li(a0, Operand(Smi::FromInt(strict_mode)));
2490 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode. 2489 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode.
2491 __ CallRuntime(Runtime::kStoreContextSlot, 4); 2490 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2492 } 2491 }
2493 2492
2494 2493
2495 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2494 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
2496 Token::Value op) {
2497 if (var->IsUnallocated()) { 2495 if (var->IsUnallocated()) {
2498 // Global var, const, or let. 2496 // Global var, const, or let.
2499 __ mov(a0, result_register()); 2497 __ mov(a0, result_register());
2500 __ li(a2, Operand(var->name())); 2498 __ li(a2, Operand(var->name()));
2501 __ lw(a1, GlobalObjectOperand()); 2499 __ lw(a1, GlobalObjectOperand());
2502 CallStoreIC(); 2500 CallStoreIC();
2503 2501
2504 } else if (op == Token::INIT_CONST) { 2502 } else if (op == Token::INIT_CONST_LEGACY) {
2505 // Const initializers need a write barrier. 2503 // Const initializers need a write barrier.
2506 ASSERT(!var->IsParameter()); // No const parameters. 2504 ASSERT(!var->IsParameter()); // No const parameters.
2507 if (var->IsLookupSlot()) { 2505 if (var->IsLookupSlot()) {
2508 __ li(a0, Operand(var->name())); 2506 __ li(a0, Operand(var->name()));
2509 __ Push(v0, cp, a0); // Context and name. 2507 __ Push(v0, cp, a0); // Context and name.
2510 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 2508 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
2511 } else { 2509 } else {
2512 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2510 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2513 Label skip; 2511 Label skip;
2514 MemOperand location = VarOperand(var, a1); 2512 MemOperand location = VarOperand(var, a1);
2515 __ lw(a2, location); 2513 __ lw(a2, location);
2516 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2514 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2517 __ Branch(&skip, ne, a2, Operand(at)); 2515 __ Branch(&skip, ne, a2, Operand(at));
2518 EmitStoreToStackLocalOrContextSlot(var, location); 2516 EmitStoreToStackLocalOrContextSlot(var, location);
2519 __ bind(&skip); 2517 __ bind(&skip);
2520 } 2518 }
2521 2519
2522 } else if (var->mode() == LET && op != Token::INIT_LET) { 2520 } else if (var->mode() == LET && op != Token::INIT_LET) {
2523 // Non-initializing assignment to let variable needs a write barrier. 2521 // Non-initializing assignment to let variable needs a write barrier.
2524 if (var->IsLookupSlot()) { 2522 if (var->IsLookupSlot()) {
2525 EmitCallStoreContextSlot(var->name(), language_mode()); 2523 EmitCallStoreContextSlot(var->name(), strict_mode());
2526 } else { 2524 } else {
2527 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2525 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2528 Label assign; 2526 Label assign;
2529 MemOperand location = VarOperand(var, a1); 2527 MemOperand location = VarOperand(var, a1);
2530 __ lw(a3, location); 2528 __ lw(a3, location);
2531 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2529 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2532 __ Branch(&assign, ne, a3, Operand(t0)); 2530 __ Branch(&assign, ne, a3, Operand(t0));
2533 __ li(a3, Operand(var->name())); 2531 __ li(a3, Operand(var->name()));
2534 __ push(a3); 2532 __ push(a3);
2535 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2533 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2536 // Perform the assignment. 2534 // Perform the assignment.
2537 __ bind(&assign); 2535 __ bind(&assign);
2538 EmitStoreToStackLocalOrContextSlot(var, location); 2536 EmitStoreToStackLocalOrContextSlot(var, location);
2539 } 2537 }
2540 2538
2541 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { 2539 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2542 // Assignment to var or initializing assignment to let/const 2540 // Assignment to var or initializing assignment to let/const
2543 // in harmony mode. 2541 // in harmony mode.
2544 if (var->IsLookupSlot()) { 2542 if (var->IsLookupSlot()) {
2545 EmitCallStoreContextSlot(var->name(), language_mode()); 2543 EmitCallStoreContextSlot(var->name(), strict_mode());
2546 } else { 2544 } else {
2547 ASSERT((var->IsStackAllocated() || var->IsContextSlot())); 2545 ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
2548 MemOperand location = VarOperand(var, a1); 2546 MemOperand location = VarOperand(var, a1);
2549 if (generate_debug_code_ && op == Token::INIT_LET) { 2547 if (generate_debug_code_ && op == Token::INIT_LET) {
2550 // Check for an uninitialized let binding. 2548 // Check for an uninitialized let binding.
2551 __ lw(a2, location); 2549 __ lw(a2, location);
2552 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2550 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2553 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0)); 2551 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0));
2554 } 2552 }
2555 EmitStoreToStackLocalOrContextSlot(var, location); 2553 EmitStoreToStackLocalOrContextSlot(var, location);
(...skipping 28 matching lines...) Expand all
2584 // Record source code position before IC call. 2582 // Record source code position before IC call.
2585 SetSourcePosition(expr->position()); 2583 SetSourcePosition(expr->position());
2586 // Call keyed store IC. 2584 // Call keyed store IC.
2587 // The arguments are: 2585 // The arguments are:
2588 // - a0 is the value, 2586 // - a0 is the value,
2589 // - a1 is the key, 2587 // - a1 is the key,
2590 // - a2 is the receiver. 2588 // - a2 is the receiver.
2591 __ mov(a0, result_register()); 2589 __ mov(a0, result_register());
2592 __ Pop(a2, a1); // a1 = key. 2590 __ Pop(a2, a1); // a1 = key.
2593 2591
2594 Handle<Code> ic = is_sloppy_mode() 2592 Handle<Code> ic = strict_mode() == SLOPPY
2595 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2593 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2596 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2594 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2597 CallIC(ic, expr->AssignmentFeedbackId()); 2595 CallIC(ic, expr->AssignmentFeedbackId());
2598 2596
2599 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2597 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2600 context()->Plug(v0); 2598 context()->Plug(v0);
2601 } 2599 }
2602 2600
2603 2601
2604 void FullCodeGenerator::VisitProperty(Property* expr) { 2602 void FullCodeGenerator::VisitProperty(Property* expr) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
2750 if (arg_count > 0) { 2748 if (arg_count > 0) {
2751 __ lw(t2, MemOperand(sp, arg_count * kPointerSize)); 2749 __ lw(t2, MemOperand(sp, arg_count * kPointerSize));
2752 } else { 2750 } else {
2753 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); 2751 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex);
2754 } 2752 }
2755 2753
2756 // t1: the receiver of the enclosing function. 2754 // t1: the receiver of the enclosing function.
2757 int receiver_offset = 2 + info_->scope()->num_parameters(); 2755 int receiver_offset = 2 + info_->scope()->num_parameters();
2758 __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize)); 2756 __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize));
2759 2757
2760 // t0: the language mode. 2758 // t0: the strict mode.
2761 __ li(t0, Operand(Smi::FromInt(language_mode()))); 2759 __ li(t0, Operand(Smi::FromInt(strict_mode())));
2762 2760
2763 // a1: the start position of the scope the calls resides in. 2761 // a1: the start position of the scope the calls resides in.
2764 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); 2762 __ li(a1, Operand(Smi::FromInt(scope()->start_position())));
2765 2763
2766 // Do the runtime call. 2764 // Do the runtime call.
2767 __ Push(t2, t1, t0, a1); 2765 __ Push(t2, t1, t0, a1);
2768 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2766 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2769 } 2767 }
2770 2768
2771 2769
(...skipping 1448 matching lines...) Expand 10 before | Expand all | Expand 10 after
4220 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4218 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4221 switch (expr->op()) { 4219 switch (expr->op()) {
4222 case Token::DELETE: { 4220 case Token::DELETE: {
4223 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4221 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4224 Property* property = expr->expression()->AsProperty(); 4222 Property* property = expr->expression()->AsProperty();
4225 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4223 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4226 4224
4227 if (property != NULL) { 4225 if (property != NULL) {
4228 VisitForStackValue(property->obj()); 4226 VisitForStackValue(property->obj());
4229 VisitForStackValue(property->key()); 4227 VisitForStackValue(property->key());
4230 StrictModeFlag strict_mode_flag = (language_mode() == SLOPPY_MODE) 4228 __ li(a1, Operand(Smi::FromInt(strict_mode())));
4231 ? kSloppyMode : kStrictMode;
4232 __ li(a1, Operand(Smi::FromInt(strict_mode_flag)));
4233 __ push(a1); 4229 __ push(a1);
4234 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4230 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4235 context()->Plug(v0); 4231 context()->Plug(v0);
4236 } else if (proxy != NULL) { 4232 } else if (proxy != NULL) {
4237 Variable* var = proxy->var(); 4233 Variable* var = proxy->var();
4238 // Delete of an unqualified identifier is disallowed in strict mode 4234 // Delete of an unqualified identifier is disallowed in strict mode
4239 // but "delete this" is allowed. 4235 // but "delete this" is allowed.
4240 ASSERT(language_mode() == SLOPPY_MODE || var->is_this()); 4236 ASSERT(strict_mode() == SLOPPY || var->is_this());
4241 if (var->IsUnallocated()) { 4237 if (var->IsUnallocated()) {
4242 __ lw(a2, GlobalObjectOperand()); 4238 __ lw(a2, GlobalObjectOperand());
4243 __ li(a1, Operand(var->name())); 4239 __ li(a1, Operand(var->name()));
4244 __ li(a0, Operand(Smi::FromInt(kSloppyMode))); 4240 __ li(a0, Operand(Smi::FromInt(SLOPPY)));
4245 __ Push(a2, a1, a0); 4241 __ Push(a2, a1, a0);
4246 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4242 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4247 context()->Plug(v0); 4243 context()->Plug(v0);
4248 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4244 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4249 // Result of deleting non-global, non-dynamic variables is false. 4245 // Result of deleting non-global, non-dynamic variables is false.
4250 // The subexpression does not have side effects. 4246 // The subexpression does not have side effects.
4251 context()->Plug(var->is_this()); 4247 context()->Plug(var->is_this());
4252 } else { 4248 } else {
4253 // Non-global variable. Call the runtime to try to delete from the 4249 // Non-global variable. Call the runtime to try to delete from the
4254 // context where the variable was introduced. 4250 // context where the variable was introduced.
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
4493 context()->PlugTOS(); 4489 context()->PlugTOS();
4494 } 4490 }
4495 } else { 4491 } else {
4496 context()->Plug(v0); 4492 context()->Plug(v0);
4497 } 4493 }
4498 break; 4494 break;
4499 } 4495 }
4500 case KEYED_PROPERTY: { 4496 case KEYED_PROPERTY: {
4501 __ mov(a0, result_register()); // Value. 4497 __ mov(a0, result_register()); // Value.
4502 __ Pop(a2, a1); // a1 = key, a2 = receiver. 4498 __ Pop(a2, a1); // a1 = key, a2 = receiver.
4503 Handle<Code> ic = is_sloppy_mode() 4499 Handle<Code> ic = strict_mode() == SLOPPY
4504 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4500 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4505 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4501 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4506 CallIC(ic, expr->CountStoreFeedbackId()); 4502 CallIC(ic, expr->CountStoreFeedbackId());
4507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4503 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4508 if (expr->is_postfix()) { 4504 if (expr->is_postfix()) {
4509 if (!context()->IsEffect()) { 4505 if (!context()->IsEffect()) {
4510 context()->PlugTOS(); 4506 context()->PlugTOS();
4511 } 4507 }
4512 } else { 4508 } else {
4513 context()->Plug(v0); 4509 context()->Plug(v0);
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
4954 Assembler::target_address_at(pc_immediate_load_address)) == 4950 Assembler::target_address_at(pc_immediate_load_address)) ==
4955 reinterpret_cast<uint32_t>( 4951 reinterpret_cast<uint32_t>(
4956 isolate->builtins()->OsrAfterStackCheck()->entry())); 4952 isolate->builtins()->OsrAfterStackCheck()->entry()));
4957 return OSR_AFTER_STACK_CHECK; 4953 return OSR_AFTER_STACK_CHECK;
4958 } 4954 }
4959 4955
4960 4956
4961 } } // namespace v8::internal 4957 } } // namespace v8::internal
4962 4958
4963 #endif // V8_TARGET_ARCH_MIPS 4959 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698