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

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

Issue 181543002: Eliminate extended mode, and other modes clean-up (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/a64/code-stubs-a64.cc ('k') | src/a64/ic-a64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 #ifdef DEBUG 141 #ifdef DEBUG
142 if (strlen(FLAG_stop_at) > 0 && 142 if (strlen(FLAG_stop_at) > 0 &&
143 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 143 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
144 __ Debug("stop-at", __LINE__, BREAK); 144 __ Debug("stop-at", __LINE__, BREAK);
145 } 145 }
146 #endif 146 #endif
147 147
148 // Sloppy mode functions and builtins need to replace the receiver with the 148 // Sloppy mode functions and builtins need to replace the receiver with the
149 // global proxy when called as functions (without an explicit receiver 149 // global proxy when called as functions (without an explicit receiver
150 // object). 150 // object).
151 if (info->is_sloppy_mode() && !info->is_native()) { 151 if (info->strict_mode() == SLOPPY && !info->is_native()) {
152 Label ok; 152 Label ok;
153 int receiver_offset = info->scope()->num_parameters() * kXRegSizeInBytes; 153 int receiver_offset = info->scope()->num_parameters() * kXRegSizeInBytes;
154 __ Peek(x10, receiver_offset); 154 __ Peek(x10, receiver_offset);
155 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok); 155 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok);
156 156
157 __ Ldr(x10, GlobalObjectMemOperand()); 157 __ Ldr(x10, GlobalObjectMemOperand());
158 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset)); 158 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset));
159 __ Poke(x10, receiver_offset); 159 __ Poke(x10, receiver_offset);
160 160
161 __ Bind(&ok); 161 __ Bind(&ok);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 int offset = num_parameters * kPointerSize; 244 int offset = num_parameters * kPointerSize;
245 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset + offset); 245 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset + offset);
246 __ Mov(x1, Operand(Smi::FromInt(num_parameters))); 246 __ Mov(x1, Operand(Smi::FromInt(num_parameters)));
247 __ Push(x3, x2, x1); 247 __ Push(x3, x2, x1);
248 248
249 // Arguments to ArgumentsAccessStub: 249 // Arguments to ArgumentsAccessStub:
250 // function, receiver address, parameter count. 250 // function, receiver address, parameter count.
251 // The stub will rewrite receiver and parameter count if the previous 251 // The stub will rewrite receiver and parameter count if the previous
252 // stack frame was an arguments adapter frame. 252 // stack frame was an arguments adapter frame.
253 ArgumentsAccessStub::Type type; 253 ArgumentsAccessStub::Type type;
254 if (!is_sloppy_mode()) { 254 if (strict_mode() == STRICT) {
255 type = ArgumentsAccessStub::NEW_STRICT; 255 type = ArgumentsAccessStub::NEW_STRICT;
256 } else if (function()->has_duplicate_parameters()) { 256 } else if (function()->has_duplicate_parameters()) {
257 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; 257 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
258 } else { 258 } else {
259 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; 259 type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
260 } 260 }
261 ArgumentsAccessStub stub(type); 261 ArgumentsAccessStub stub(type);
262 __ CallStub(&stub); 262 __ CallStub(&stub);
263 263
264 SetVar(arguments, x0, x1, x2); 264 SetVar(arguments, x0, x1, x2);
265 } 265 }
266 266
267 if (FLAG_trace) { 267 if (FLAG_trace) {
268 __ CallRuntime(Runtime::kTraceEnter, 0); 268 __ CallRuntime(Runtime::kTraceEnter, 0);
269 } 269 }
270 270
271 271
272 // Visit the declarations and body unless there is an illegal 272 // Visit the declarations and body unless there is an illegal
273 // redeclaration. 273 // redeclaration.
274 if (scope()->HasIllegalRedeclaration()) { 274 if (scope()->HasIllegalRedeclaration()) {
275 Comment cmnt(masm_, "[ Declarations"); 275 Comment cmnt(masm_, "[ Declarations");
276 scope()->VisitIllegalRedeclaration(this); 276 scope()->VisitIllegalRedeclaration(this);
277 277
278 } else { 278 } else {
279 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 279 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
280 { Comment cmnt(masm_, "[ Declarations"); 280 { Comment cmnt(masm_, "[ Declarations");
281 if (scope()->is_function_scope() && scope()->function() != NULL) { 281 if (scope()->is_function_scope() && scope()->function() != NULL) {
282 VariableDeclaration* function = scope()->function(); 282 VariableDeclaration* function = scope()->function();
283 ASSERT(function->proxy()->var()->mode() == CONST || 283 ASSERT(function->proxy()->var()->mode() == CONST ||
284 function->proxy()->var()->mode() == CONST_HARMONY); 284 function->proxy()->var()->mode() == CONST_LEGACY);
285 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); 285 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
286 VisitVariableDeclaration(function); 286 VisitVariableDeclaration(function);
287 } 287 }
288 VisitDeclarations(scope()->declarations()); 288 VisitDeclarations(scope()->declarations());
289 } 289 }
290 } 290 }
291 291
292 { Comment cmnt(masm_, "[ Stack check"); 292 { Comment cmnt(masm_, "[ Stack check");
293 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 293 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
294 Label ok; 294 Label ok;
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 785
786 786
787 void FullCodeGenerator::VisitVariableDeclaration( 787 void FullCodeGenerator::VisitVariableDeclaration(
788 VariableDeclaration* declaration) { 788 VariableDeclaration* declaration) {
789 // If it was not possible to allocate the variable at compile time, we 789 // If it was not possible to allocate the variable at compile time, we
790 // need to "declare" it at runtime to make sure it actually exists in the 790 // need to "declare" it at runtime to make sure it actually exists in the
791 // local context. 791 // local context.
792 VariableProxy* proxy = declaration->proxy(); 792 VariableProxy* proxy = declaration->proxy();
793 VariableMode mode = declaration->mode(); 793 VariableMode mode = declaration->mode();
794 Variable* variable = proxy->var(); 794 Variable* variable = proxy->var();
795 bool hole_init = (mode == CONST) || (mode == CONST_HARMONY) || (mode == LET); 795 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
796 796
797 switch (variable->location()) { 797 switch (variable->location()) {
798 case Variable::UNALLOCATED: 798 case Variable::UNALLOCATED:
799 globals_->Add(variable->name(), zone()); 799 globals_->Add(variable->name(), zone());
800 globals_->Add(variable->binding_needs_init() 800 globals_->Add(variable->binding_needs_init()
801 ? isolate()->factory()->the_hole_value() 801 ? isolate()->factory()->the_hole_value()
802 : isolate()->factory()->undefined_value(), 802 : isolate()->factory()->undefined_value(),
803 zone()); 803 zone());
804 break; 804 break;
805 805
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 // nested functions that don't need literals cloning. If we're running with 1319 // nested functions that don't need literals cloning. If we're running with
1320 // the --always-opt or the --prepare-always-opt flag, we need to use the 1320 // the --always-opt or the --prepare-always-opt flag, we need to use the
1321 // runtime function so that the new function we are creating here gets a 1321 // runtime function so that the new function we are creating here gets a
1322 // chance to have its code optimized and doesn't just get a copy of the 1322 // chance to have its code optimized and doesn't just get a copy of the
1323 // existing unoptimized code. 1323 // existing unoptimized code.
1324 if (!FLAG_always_opt && 1324 if (!FLAG_always_opt &&
1325 !FLAG_prepare_always_opt && 1325 !FLAG_prepare_always_opt &&
1326 !pretenure && 1326 !pretenure &&
1327 scope()->is_function_scope() && 1327 scope()->is_function_scope() &&
1328 info->num_literals() == 0) { 1328 info->num_literals() == 0) {
1329 FastNewClosureStub stub(info->language_mode(), info->is_generator()); 1329 FastNewClosureStub stub(info->strict_mode(), info->is_generator());
1330 __ Mov(x2, Operand(info)); 1330 __ Mov(x2, Operand(info));
1331 __ CallStub(&stub); 1331 __ CallStub(&stub);
1332 } else { 1332 } else {
1333 __ Mov(x11, Operand(info)); 1333 __ Mov(x11, Operand(info));
1334 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex 1334 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex
1335 : Heap::kFalseValueRootIndex); 1335 : Heap::kFalseValueRootIndex);
1336 __ Push(cp, x11, x10); 1336 __ Push(cp, x11, x10);
1337 __ CallRuntime(Runtime::kNewClosure, 3); 1337 __ CallRuntime(Runtime::kNewClosure, 3);
1338 } 1338 }
1339 context()->Plug(x0); 1339 context()->Plug(x0);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 // eval-introduced variables. Eval is used a lot without 1435 // eval-introduced variables. Eval is used a lot without
1436 // introducing variables. In those cases, we do not want to 1436 // introducing variables. In those cases, we do not want to
1437 // perform a runtime call for all variables in the scope 1437 // perform a runtime call for all variables in the scope
1438 // containing the eval. 1438 // containing the eval.
1439 if (var->mode() == DYNAMIC_GLOBAL) { 1439 if (var->mode() == DYNAMIC_GLOBAL) {
1440 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 1440 EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
1441 __ B(done); 1441 __ B(done);
1442 } else if (var->mode() == DYNAMIC_LOCAL) { 1442 } else if (var->mode() == DYNAMIC_LOCAL) {
1443 Variable* local = var->local_if_not_shadowed(); 1443 Variable* local = var->local_if_not_shadowed();
1444 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow)); 1444 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow));
1445 if (local->mode() == LET || 1445 if (local->mode() == LET || local->mode() == CONST ||
1446 local->mode() == CONST || 1446 local->mode() == CONST_LEGACY) {
1447 local->mode() == CONST_HARMONY) {
1448 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done); 1447 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done);
1449 if (local->mode() == CONST) { 1448 if (local->mode() == CONST_LEGACY) {
1450 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1449 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1451 } else { // LET || CONST_HARMONY 1450 } else { // LET || CONST
1452 __ Mov(x0, Operand(var->name())); 1451 __ Mov(x0, Operand(var->name()));
1453 __ Push(x0); 1452 __ Push(x0);
1454 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1453 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1455 } 1454 }
1456 } 1455 }
1457 __ B(done); 1456 __ B(done);
1458 } 1457 }
1459 } 1458 }
1460 1459
1461 1460
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1508 // binding is initialized: 1507 // binding is initialized:
1509 // function() { f(); let x = 1; function f() { x = 2; } } 1508 // function() { f(); let x = 1; function f() { x = 2; } }
1510 // 1509 //
1511 bool skip_init_check; 1510 bool skip_init_check;
1512 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1511 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
1513 skip_init_check = false; 1512 skip_init_check = false;
1514 } else { 1513 } else {
1515 // Check that we always have valid source position. 1514 // Check that we always have valid source position.
1516 ASSERT(var->initializer_position() != RelocInfo::kNoPosition); 1515 ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
1517 ASSERT(proxy->position() != RelocInfo::kNoPosition); 1516 ASSERT(proxy->position() != RelocInfo::kNoPosition);
1518 skip_init_check = var->mode() != CONST && 1517 skip_init_check = var->mode() != CONST_LEGACY &&
1519 var->initializer_position() < proxy->position(); 1518 var->initializer_position() < proxy->position();
1520 } 1519 }
1521 1520
1522 if (!skip_init_check) { 1521 if (!skip_init_check) {
1523 // Let and const need a read barrier. 1522 // Let and const need a read barrier.
1524 GetVar(x0, var); 1523 GetVar(x0, var);
1525 Label done; 1524 Label done;
1526 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done); 1525 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done);
1527 if (var->mode() == LET || var->mode() == CONST_HARMONY) { 1526 if (var->mode() == LET || var->mode() == CONST) {
1528 // Throw a reference error when using an uninitialized let/const 1527 // Throw a reference error when using an uninitialized let/const
1529 // binding in harmony mode. 1528 // binding in harmony mode.
1530 __ Mov(x0, Operand(var->name())); 1529 __ Mov(x0, Operand(var->name()));
1531 __ Push(x0); 1530 __ Push(x0);
1532 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1531 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1533 __ Bind(&done); 1532 __ Bind(&done);
1534 } else { 1533 } else {
1535 // Uninitalized const bindings outside of harmony mode are unholed. 1534 // Uninitalized const bindings outside of harmony mode are unholed.
1536 ASSERT(var->mode() == CONST); 1535 ASSERT(var->mode() == CONST_LEGACY);
1537 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1536 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1538 __ Bind(&done); 1537 __ Bind(&done);
1539 } 1538 }
1540 context()->Plug(x0); 1539 context()->Plug(x0);
1541 break; 1540 break;
1542 } 1541 }
1543 } 1542 }
1544 context()->Plug(var); 1543 context()->Plug(var);
1545 break; 1544 break;
1546 } 1545 }
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 __ Mov(x2, Operand(prop->key()->AsLiteral()->value())); 2136 __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
2138 CallStoreIC(); 2137 CallStoreIC();
2139 break; 2138 break;
2140 } 2139 }
2141 case KEYED_PROPERTY: { 2140 case KEYED_PROPERTY: {
2142 __ Push(x0); // Preserve value. 2141 __ Push(x0); // Preserve value.
2143 VisitForStackValue(prop->obj()); 2142 VisitForStackValue(prop->obj());
2144 VisitForAccumulatorValue(prop->key()); 2143 VisitForAccumulatorValue(prop->key());
2145 __ Mov(x1, x0); 2144 __ Mov(x1, x0);
2146 __ Pop(x2, x0); 2145 __ Pop(x2, x0);
2147 Handle<Code> ic = is_sloppy_mode() 2146 Handle<Code> ic = strict_mode() == SLOPPY
2148 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2147 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2149 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2148 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2150 CallIC(ic); 2149 CallIC(ic);
2151 break; 2150 break;
2152 } 2151 }
2153 } 2152 }
2154 context()->Plug(x0); 2153 context()->Plug(x0);
2155 } 2154 }
2156 2155
2157 2156
2158 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2157 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2159 Variable* var, MemOperand location) { 2158 Variable* var, MemOperand location) {
2160 __ Str(result_register(), location); 2159 __ Str(result_register(), location);
2161 if (var->IsContextSlot()) { 2160 if (var->IsContextSlot()) {
2162 // RecordWrite may destroy all its register arguments. 2161 // RecordWrite may destroy all its register arguments.
2163 __ Mov(x10, result_register()); 2162 __ Mov(x10, result_register());
2164 int offset = Context::SlotOffset(var->index()); 2163 int offset = Context::SlotOffset(var->index());
2165 __ RecordWriteContextSlot( 2164 __ RecordWriteContextSlot(
2166 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); 2165 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs);
2167 } 2166 }
2168 } 2167 }
2169 2168
2170 2169
2171 void FullCodeGenerator::EmitCallStoreContextSlot( 2170 void FullCodeGenerator::EmitCallStoreContextSlot(
2172 Handle<String> name, LanguageMode mode) { 2171 Handle<String> name, StrictMode strict_mode) {
2173 __ Mov(x11, Operand(name)); 2172 __ Mov(x11, Operand(name));
2174 __ Mov(x10, Operand(Smi::FromInt(mode))); 2173 __ Mov(x10, Operand(Smi::FromInt(strict_mode)));
2175 // jssp[0] : mode. 2174 // jssp[0] : mode.
2176 // jssp[8] : name. 2175 // jssp[8] : name.
2177 // jssp[16] : context. 2176 // jssp[16] : context.
2178 // jssp[24] : value. 2177 // jssp[24] : value.
2179 __ Push(x0, cp, x11, x10); 2178 __ Push(x0, cp, x11, x10);
2180 __ CallRuntime(Runtime::kStoreContextSlot, 4); 2179 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2181 } 2180 }
2182 2181
2183 2182
2184 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2183 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2185 Token::Value op) { 2184 Token::Value op) {
2186 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); 2185 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment");
2187 if (var->IsUnallocated()) { 2186 if (var->IsUnallocated()) {
2188 // Global var, const, or let. 2187 // Global var, const, or let.
2189 __ Mov(x2, Operand(var->name())); 2188 __ Mov(x2, Operand(var->name()));
2190 __ Ldr(x1, GlobalObjectMemOperand()); 2189 __ Ldr(x1, GlobalObjectMemOperand());
2191 CallStoreIC(); 2190 CallStoreIC();
2192 2191
2193 } else if (op == Token::INIT_CONST) { 2192 } else if (op == Token::INIT_CONST_LEGACY) {
2194 // Const initializers need a write barrier. 2193 // Const initializers need a write barrier.
2195 ASSERT(!var->IsParameter()); // No const parameters. 2194 ASSERT(!var->IsParameter()); // No const parameters.
2196 if (var->IsLookupSlot()) { 2195 if (var->IsLookupSlot()) {
2197 __ Push(x0); 2196 __ Push(x0);
2198 __ Mov(x0, Operand(var->name())); 2197 __ Mov(x0, Operand(var->name()));
2199 __ Push(cp, x0); // Context and name. 2198 __ Push(cp, x0); // Context and name.
2200 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 2199 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
2201 } else { 2200 } else {
2202 ASSERT(var->IsStackLocal() || var->IsContextSlot()); 2201 ASSERT(var->IsStackLocal() || var->IsContextSlot());
2203 Label skip; 2202 Label skip;
2204 MemOperand location = VarOperand(var, x1); 2203 MemOperand location = VarOperand(var, x1);
2205 __ Ldr(x10, location); 2204 __ Ldr(x10, location);
2206 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); 2205 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip);
2207 EmitStoreToStackLocalOrContextSlot(var, location); 2206 EmitStoreToStackLocalOrContextSlot(var, location);
2208 __ Bind(&skip); 2207 __ Bind(&skip);
2209 } 2208 }
2210 2209
2211 } else if (var->mode() == LET && op != Token::INIT_LET) { 2210 } else if (var->mode() == LET && op != Token::INIT_LET) {
2212 // Non-initializing assignment to let variable needs a write barrier. 2211 // Non-initializing assignment to let variable needs a write barrier.
2213 if (var->IsLookupSlot()) { 2212 if (var->IsLookupSlot()) {
2214 EmitCallStoreContextSlot(var->name(), language_mode()); 2213 EmitCallStoreContextSlot(var->name(), strict_mode());
2215 } else { 2214 } else {
2216 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2215 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2217 Label assign; 2216 Label assign;
2218 MemOperand location = VarOperand(var, x1); 2217 MemOperand location = VarOperand(var, x1);
2219 __ Ldr(x10, location); 2218 __ Ldr(x10, location);
2220 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); 2219 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign);
2221 __ Mov(x10, Operand(var->name())); 2220 __ Mov(x10, Operand(var->name()));
2222 __ Push(x10); 2221 __ Push(x10);
2223 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2222 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2224 // Perform the assignment. 2223 // Perform the assignment.
2225 __ Bind(&assign); 2224 __ Bind(&assign);
2226 EmitStoreToStackLocalOrContextSlot(var, location); 2225 EmitStoreToStackLocalOrContextSlot(var, location);
2227 } 2226 }
2228 2227
2229 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { 2228 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2230 // Assignment to var or initializing assignment to let/const 2229 // Assignment to var or initializing assignment to let/const
2231 // in harmony mode. 2230 // in harmony mode.
2232 if (var->IsLookupSlot()) { 2231 if (var->IsLookupSlot()) {
2233 EmitCallStoreContextSlot(var->name(), language_mode()); 2232 EmitCallStoreContextSlot(var->name(), strict_mode());
2234 } else { 2233 } else {
2235 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2234 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2236 MemOperand location = VarOperand(var, x1); 2235 MemOperand location = VarOperand(var, x1);
2237 if (FLAG_debug_code && op == Token::INIT_LET) { 2236 if (FLAG_debug_code && op == Token::INIT_LET) {
2238 __ Ldr(x10, location); 2237 __ Ldr(x10, location);
2239 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); 2238 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex);
2240 __ Check(eq, kLetBindingReInitialization); 2239 __ Check(eq, kLetBindingReInitialization);
2241 } 2240 }
2242 EmitStoreToStackLocalOrContextSlot(var, location); 2241 EmitStoreToStackLocalOrContextSlot(var, location);
2243 } 2242 }
(...skipping 23 matching lines...) Expand all
2267 2266
2268 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2267 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2269 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); 2268 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment");
2270 // Assignment to a property, using a keyed store IC. 2269 // Assignment to a property, using a keyed store IC.
2271 2270
2272 // Record source code position before IC call. 2271 // Record source code position before IC call.
2273 SetSourcePosition(expr->position()); 2272 SetSourcePosition(expr->position());
2274 // TODO(all): Could we pass this in registers rather than on the stack? 2273 // TODO(all): Could we pass this in registers rather than on the stack?
2275 __ Pop(x1, x2); // Key and object holding the property. 2274 __ Pop(x1, x2); // Key and object holding the property.
2276 2275
2277 Handle<Code> ic = is_sloppy_mode() 2276 Handle<Code> ic = strict_mode() == SLOPPY
2278 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2277 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2279 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2278 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2280 CallIC(ic, expr->AssignmentFeedbackId()); 2279 CallIC(ic, expr->AssignmentFeedbackId());
2281 2280
2282 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2281 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2283 context()->Plug(x0); 2282 context()->Plug(x0);
2284 } 2283 }
2285 2284
2286 2285
2287 void FullCodeGenerator::VisitProperty(Property* expr) { 2286 void FullCodeGenerator::VisitProperty(Property* expr) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
2445 } 2444 }
2446 2445
2447 // Prepare to push the receiver of the enclosing function. 2446 // Prepare to push the receiver of the enclosing function.
2448 int receiver_offset = 2 + info_->scope()->num_parameters(); 2447 int receiver_offset = 2 + info_->scope()->num_parameters();
2449 __ Ldr(x11, MemOperand(fp, receiver_offset * kPointerSize)); 2448 __ Ldr(x11, MemOperand(fp, receiver_offset * kPointerSize));
2450 2449
2451 // Push. 2450 // Push.
2452 __ Push(x10, x11); 2451 __ Push(x10, x11);
2453 2452
2454 // Prepare to push the language mode. 2453 // Prepare to push the language mode.
2455 __ Mov(x10, Operand(Smi::FromInt(language_mode()))); 2454 __ Mov(x10, Operand(Smi::FromInt(strict_mode())));
2456 // Prepare to push the start position of the scope the calls resides in. 2455 // Prepare to push the start position of the scope the calls resides in.
2457 __ Mov(x11, Operand(Smi::FromInt(scope()->start_position()))); 2456 __ Mov(x11, Operand(Smi::FromInt(scope()->start_position())));
2458 2457
2459 // Push. 2458 // Push.
2460 __ Push(x10, x11); 2459 __ Push(x10, x11);
2461 2460
2462 // Do the runtime call. 2461 // Do the runtime call.
2463 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2462 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2464 } 2463 }
2465 2464
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after
3885 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3884 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3886 switch (expr->op()) { 3885 switch (expr->op()) {
3887 case Token::DELETE: { 3886 case Token::DELETE: {
3888 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3887 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3889 Property* property = expr->expression()->AsProperty(); 3888 Property* property = expr->expression()->AsProperty();
3890 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3889 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3891 3890
3892 if (property != NULL) { 3891 if (property != NULL) {
3893 VisitForStackValue(property->obj()); 3892 VisitForStackValue(property->obj());
3894 VisitForStackValue(property->key()); 3893 VisitForStackValue(property->key());
3895 StrictModeFlag strict_mode_flag = (language_mode() == SLOPPY_MODE) 3894 __ Mov(x10, Operand(Smi::FromInt(strict_mode())));
3896 ? kSloppyMode : kStrictMode;
3897 __ Mov(x10, Operand(Smi::FromInt(strict_mode_flag)));
3898 __ Push(x10); 3895 __ Push(x10);
3899 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3896 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3900 context()->Plug(x0); 3897 context()->Plug(x0);
3901 } else if (proxy != NULL) { 3898 } else if (proxy != NULL) {
3902 Variable* var = proxy->var(); 3899 Variable* var = proxy->var();
3903 // Delete of an unqualified identifier is disallowed in strict mode 3900 // Delete of an unqualified identifier is disallowed in strict mode
3904 // but "delete this" is allowed. 3901 // but "delete this" is allowed.
3905 ASSERT(language_mode() == SLOPPY_MODE || var->is_this()); 3902 ASSERT(strict_mode() == SLOPPY || var->is_this());
3906 if (var->IsUnallocated()) { 3903 if (var->IsUnallocated()) {
3907 __ Ldr(x12, GlobalObjectMemOperand()); 3904 __ Ldr(x12, GlobalObjectMemOperand());
3908 __ Mov(x11, Operand(var->name())); 3905 __ Mov(x11, Operand(var->name()));
3909 __ Mov(x10, Operand(Smi::FromInt(kSloppyMode))); 3906 __ Mov(x10, Operand(Smi::FromInt(SLOPPY)));
3910 __ Push(x12, x11, x10); 3907 __ Push(x12, x11, x10);
3911 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3908 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3912 context()->Plug(x0); 3909 context()->Plug(x0);
3913 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 3910 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
3914 // Result of deleting non-global, non-dynamic variables is false. 3911 // Result of deleting non-global, non-dynamic variables is false.
3915 // The subexpression does not have side effects. 3912 // The subexpression does not have side effects.
3916 context()->Plug(var->is_this()); 3913 context()->Plug(var->is_this());
3917 } else { 3914 } else {
3918 // Non-global variable. Call the runtime to try to delete from the 3915 // Non-global variable. Call the runtime to try to delete from the
3919 // context where the variable was introduced. 3916 // context where the variable was introduced.
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
4156 context()->PlugTOS(); 4153 context()->PlugTOS();
4157 } 4154 }
4158 } else { 4155 } else {
4159 context()->Plug(x0); 4156 context()->Plug(x0);
4160 } 4157 }
4161 break; 4158 break;
4162 } 4159 }
4163 case KEYED_PROPERTY: { 4160 case KEYED_PROPERTY: {
4164 __ Pop(x1); // Key. 4161 __ Pop(x1); // Key.
4165 __ Pop(x2); // Receiver. 4162 __ Pop(x2); // Receiver.
4166 Handle<Code> ic = is_sloppy_mode() 4163 Handle<Code> ic = strict_mode() == SLOPPY
4167 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4164 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4168 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4165 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4169 CallIC(ic, expr->CountStoreFeedbackId()); 4166 CallIC(ic, expr->CountStoreFeedbackId());
4170 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4167 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4171 if (expr->is_postfix()) { 4168 if (expr->is_postfix()) {
4172 if (!context()->IsEffect()) { 4169 if (!context()->IsEffect()) {
4173 context()->PlugTOS(); 4170 context()->PlugTOS();
4174 } 4171 }
4175 } else { 4172 } else {
4176 context()->Plug(x0); 4173 context()->Plug(x0);
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
4984 return previous_; 4981 return previous_;
4985 } 4982 }
4986 4983
4987 4984
4988 #undef __ 4985 #undef __
4989 4986
4990 4987
4991 } } // namespace v8::internal 4988 } } // namespace v8::internal
4992 4989
4993 #endif // V8_TARGET_ARCH_A64 4990 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/code-stubs-a64.cc ('k') | src/a64/ic-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698