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

Side by Side Diff: src/ia32/full-codegen-ia32.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_IA32 7 #if V8_TARGET_ARCH_IA32
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 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1290 Immediate(isolate()->factory()->home_object_symbol())); 1290 Immediate(isolate()->factory()->home_object_symbol()));
1291 __ mov(StoreDescriptor::ValueRegister(), 1291 __ mov(StoreDescriptor::ValueRegister(),
1292 Operand(esp, offset * kPointerSize)); 1292 Operand(esp, offset * kPointerSize));
1293 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); 1293 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1294 CallStoreIC(); 1294 CallStoreIC();
1295 } 1295 }
1296 } 1296 }
1297 1297
1298 1298
1299 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1299 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1300 TypeofState typeof_state, 1300 TypeofMode typeof_mode,
1301 Label* slow) { 1301 Label* slow) {
1302 Register context = esi; 1302 Register context = esi;
1303 Register temp = edx; 1303 Register temp = edx;
1304 1304
1305 Scope* s = scope(); 1305 Scope* s = scope();
1306 while (s != NULL) { 1306 while (s != NULL) {
1307 if (s->num_heap_slots() > 0) { 1307 if (s->num_heap_slots() > 0) {
1308 if (s->calls_sloppy_eval()) { 1308 if (s->calls_sloppy_eval()) {
1309 // Check that extension is NULL. 1309 // Check that extension is NULL.
1310 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), 1310 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX),
(...skipping 28 matching lines...) Expand all
1339 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1339 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
1340 __ j(not_equal, slow); 1340 __ j(not_equal, slow);
1341 // Load next context in chain. 1341 // Load next context in chain.
1342 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 1342 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
1343 __ jmp(&next); 1343 __ jmp(&next);
1344 __ bind(&fast); 1344 __ bind(&fast);
1345 } 1345 }
1346 1346
1347 // All extension objects were empty and it is safe to use a normal global 1347 // All extension objects were empty and it is safe to use a normal global
1348 // load machinery. 1348 // load machinery.
1349 EmitGlobalVariableLoad(proxy, typeof_state); 1349 EmitGlobalVariableLoad(proxy, typeof_mode);
1350 } 1350 }
1351 1351
1352 1352
1353 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1353 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1354 Label* slow) { 1354 Label* slow) {
1355 DCHECK(var->IsContextSlot()); 1355 DCHECK(var->IsContextSlot());
1356 Register context = esi; 1356 Register context = esi;
1357 Register temp = ebx; 1357 Register temp = ebx;
1358 1358
1359 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1359 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
(...skipping 14 matching lines...) Expand all
1374 __ j(not_equal, slow); 1374 __ j(not_equal, slow);
1375 1375
1376 // This function is used only for loads, not stores, so it's safe to 1376 // This function is used only for loads, not stores, so it's safe to
1377 // return an esi-based operand (the write barrier cannot be allowed to 1377 // return an esi-based operand (the write barrier cannot be allowed to
1378 // destroy the esi register). 1378 // destroy the esi register).
1379 return ContextOperand(context, var->index()); 1379 return ContextOperand(context, var->index());
1380 } 1380 }
1381 1381
1382 1382
1383 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, 1383 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1384 TypeofState typeof_state, 1384 TypeofMode typeof_mode,
1385 Label* slow, 1385 Label* slow, Label* done) {
1386 Label* done) {
1387 // Generate fast-case code for variables that might be shadowed by 1386 // Generate fast-case code for variables that might be shadowed by
1388 // eval-introduced variables. Eval is used a lot without 1387 // eval-introduced variables. Eval is used a lot without
1389 // introducing variables. In those cases, we do not want to 1388 // introducing variables. In those cases, we do not want to
1390 // perform a runtime call for all variables in the scope 1389 // perform a runtime call for all variables in the scope
1391 // containing the eval. 1390 // containing the eval.
1392 Variable* var = proxy->var(); 1391 Variable* var = proxy->var();
1393 if (var->mode() == DYNAMIC_GLOBAL) { 1392 if (var->mode() == DYNAMIC_GLOBAL) {
1394 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); 1393 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1395 __ jmp(done); 1394 __ jmp(done);
1396 } else if (var->mode() == DYNAMIC_LOCAL) { 1395 } else if (var->mode() == DYNAMIC_LOCAL) {
1397 Variable* local = var->local_if_not_shadowed(); 1396 Variable* local = var->local_if_not_shadowed();
1398 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); 1397 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
1399 if (local->mode() == LET || local->mode() == CONST || 1398 if (local->mode() == LET || local->mode() == CONST ||
1400 local->mode() == CONST_LEGACY) { 1399 local->mode() == CONST_LEGACY) {
1401 __ cmp(eax, isolate()->factory()->the_hole_value()); 1400 __ cmp(eax, isolate()->factory()->the_hole_value());
1402 __ j(not_equal, done); 1401 __ j(not_equal, done);
1403 if (local->mode() == CONST_LEGACY) { 1402 if (local->mode() == CONST_LEGACY) {
1404 __ mov(eax, isolate()->factory()->undefined_value()); 1403 __ mov(eax, isolate()->factory()->undefined_value());
1405 } else { // LET || CONST 1404 } else { // LET || CONST
1406 __ push(Immediate(var->name())); 1405 __ push(Immediate(var->name()));
1407 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1406 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1408 } 1407 }
1409 } 1408 }
1410 __ jmp(done); 1409 __ jmp(done);
1411 } 1410 }
1412 } 1411 }
1413 1412
1414 1413
1415 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1414 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1416 TypeofState typeof_state) { 1415 TypeofMode typeof_mode) {
1417 Variable* var = proxy->var(); 1416 Variable* var = proxy->var();
1418 DCHECK(var->IsUnallocatedOrGlobalSlot() || 1417 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1419 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); 1418 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1420 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1419 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1421 __ mov(LoadDescriptor::NameRegister(), var->name()); 1420 __ mov(LoadDescriptor::NameRegister(), var->name());
1422 __ mov(LoadDescriptor::SlotRegister(), 1421 __ mov(LoadDescriptor::SlotRegister(),
1423 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1422 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
1424 // Inside typeof use a regular load, not a contextual load, to avoid 1423 CallLoadIC(typeof_mode);
1425 // a reference error.
1426 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
1427 } 1424 }
1428 1425
1429 1426
1430 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1427 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1431 TypeofState typeof_state) { 1428 TypeofMode typeof_mode) {
1432 SetExpressionPosition(proxy); 1429 SetExpressionPosition(proxy);
1433 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1430 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1434 Variable* var = proxy->var(); 1431 Variable* var = proxy->var();
1435 1432
1436 // Three cases: global variables, lookup variables, and all other types of 1433 // Three cases: global variables, lookup variables, and all other types of
1437 // variables. 1434 // variables.
1438 switch (var->location()) { 1435 switch (var->location()) {
1439 case VariableLocation::GLOBAL: 1436 case VariableLocation::GLOBAL:
1440 case VariableLocation::UNALLOCATED: { 1437 case VariableLocation::UNALLOCATED: {
1441 Comment cmnt(masm_, "[ Global variable"); 1438 Comment cmnt(masm_, "[ Global variable");
1442 EmitGlobalVariableLoad(proxy, typeof_state); 1439 EmitGlobalVariableLoad(proxy, typeof_mode);
1443 context()->Plug(eax); 1440 context()->Plug(eax);
1444 break; 1441 break;
1445 } 1442 }
1446 1443
1447 case VariableLocation::PARAMETER: 1444 case VariableLocation::PARAMETER:
1448 case VariableLocation::LOCAL: 1445 case VariableLocation::LOCAL:
1449 case VariableLocation::CONTEXT: { 1446 case VariableLocation::CONTEXT: {
1450 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); 1447 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1451 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1448 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1452 : "[ Stack variable"); 1449 : "[ Stack variable");
1453 if (var->binding_needs_init()) { 1450 if (var->binding_needs_init()) {
1454 // var->scope() may be NULL when the proxy is located in eval code and 1451 // var->scope() may be NULL when the proxy is located in eval code and
1455 // refers to a potential outside binding. Currently those bindings are 1452 // refers to a potential outside binding. Currently those bindings are
1456 // always looked up dynamically, i.e. in that case 1453 // always looked up dynamically, i.e. in that case
1457 // var->location() == LOOKUP. 1454 // var->location() == LOOKUP.
1458 // always holds. 1455 // always holds.
1459 DCHECK(var->scope() != NULL); 1456 DCHECK(var->scope() != NULL);
1460 1457
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 } 1510 }
1514 context()->Plug(var); 1511 context()->Plug(var);
1515 break; 1512 break;
1516 } 1513 }
1517 1514
1518 case VariableLocation::LOOKUP: { 1515 case VariableLocation::LOOKUP: {
1519 Comment cmnt(masm_, "[ Lookup variable"); 1516 Comment cmnt(masm_, "[ Lookup variable");
1520 Label done, slow; 1517 Label done, slow;
1521 // Generate code for loading from variables potentially shadowed 1518 // Generate code for loading from variables potentially shadowed
1522 // by eval-introduced variables. 1519 // by eval-introduced variables.
1523 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); 1520 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1524 __ bind(&slow); 1521 __ bind(&slow);
1525 __ push(esi); // Context. 1522 __ push(esi); // Context.
1526 __ push(Immediate(var->name())); 1523 __ push(Immediate(var->name()));
1527 Runtime::FunctionId function_id = 1524 Runtime::FunctionId function_id =
1528 typeof_state == NOT_INSIDE_TYPEOF 1525 typeof_mode == NOT_INSIDE_TYPEOF
1529 ? Runtime::kLoadLookupSlot 1526 ? Runtime::kLoadLookupSlot
1530 : Runtime::kLoadLookupSlotNoReferenceError; 1527 : Runtime::kLoadLookupSlotNoReferenceError;
1531 __ CallRuntime(function_id, 2); 1528 __ CallRuntime(function_id, 2);
1532 __ bind(&done); 1529 __ bind(&done);
1533 context()->Plug(eax); 1530 context()->Plug(eax);
1534 break; 1531 break;
1535 } 1532 }
1536 } 1533 }
1537 } 1534 }
1538 1535
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
2201 __ Drop(1); // The function is still on the stack; drop it. 2198 __ Drop(1); // The function is still on the stack; drop it.
2202 2199
2203 // if (!result.done) goto l_try; 2200 // if (!result.done) goto l_try;
2204 __ bind(&l_loop); 2201 __ bind(&l_loop);
2205 __ push(eax); // save result 2202 __ push(eax); // save result
2206 __ Move(load_receiver, eax); // result 2203 __ Move(load_receiver, eax); // result
2207 __ mov(load_name, 2204 __ mov(load_name,
2208 isolate()->factory()->done_string()); // "done" 2205 isolate()->factory()->done_string()); // "done"
2209 __ mov(LoadDescriptor::SlotRegister(), 2206 __ mov(LoadDescriptor::SlotRegister(),
2210 Immediate(SmiFromSlot(expr->DoneFeedbackSlot()))); 2207 Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
2211 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax 2208 CallLoadIC(INSIDE_TYPEOF); // result.done in eax
2212 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2209 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2213 CallIC(bool_ic); 2210 CallIC(bool_ic);
2214 __ test(eax, eax); 2211 __ test(eax, eax);
2215 __ j(zero, &l_try); 2212 __ j(zero, &l_try);
2216 2213
2217 // result.value 2214 // result.value
2218 __ pop(load_receiver); // result 2215 __ pop(load_receiver); // result
2219 __ mov(load_name, 2216 __ mov(load_name,
2220 isolate()->factory()->value_string()); // "value" 2217 isolate()->factory()->value_string()); // "value"
2221 __ mov(LoadDescriptor::SlotRegister(), 2218 __ mov(LoadDescriptor::SlotRegister(),
2222 Immediate(SmiFromSlot(expr->ValueFeedbackSlot()))); 2219 Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
2223 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax 2220 CallLoadIC(INSIDE_TYPEOF); // result.value in eax
2224 context()->DropAndPlug(2, eax); // drop iter and g 2221 context()->DropAndPlug(2, eax); // drop iter and g
2225 break; 2222 break;
2226 } 2223 }
2227 } 2224 }
2228 } 2225 }
2229 2226
2230 2227
2231 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2228 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2232 Expression *value, 2229 Expression *value,
2233 JSGeneratorObject::ResumeMode resume_mode) { 2230 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2352 2349
2353 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2350 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2354 SetExpressionPosition(prop); 2351 SetExpressionPosition(prop);
2355 Literal* key = prop->key()->AsLiteral(); 2352 Literal* key = prop->key()->AsLiteral();
2356 DCHECK(!key->value()->IsSmi()); 2353 DCHECK(!key->value()->IsSmi());
2357 DCHECK(!prop->IsSuperAccess()); 2354 DCHECK(!prop->IsSuperAccess());
2358 2355
2359 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); 2356 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
2360 __ mov(LoadDescriptor::SlotRegister(), 2357 __ mov(LoadDescriptor::SlotRegister(),
2361 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2358 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
2362 CallLoadIC(NOT_CONTEXTUAL, language_mode()); 2359 CallLoadIC(INSIDE_TYPEOF, language_mode());
2363 } 2360 }
2364 2361
2365 2362
2366 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2363 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2367 // Stack: receiver, home_object. 2364 // Stack: receiver, home_object.
2368 SetExpressionPosition(prop); 2365 SetExpressionPosition(prop);
2369 Literal* key = prop->key()->AsLiteral(); 2366 Literal* key = prop->key()->AsLiteral();
2370 DCHECK(!key->value()->IsSmi()); 2367 DCHECK(!key->value()->IsSmi());
2371 DCHECK(prop->IsSuperAccess()); 2368 DCHECK(prop->IsSuperAccess());
2372 2369
(...skipping 2275 matching lines...) Expand 10 before | Expand all | Expand 10 after
4648 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 4645 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4649 // Push the builtins object as receiver. 4646 // Push the builtins object as receiver.
4650 __ mov(eax, GlobalObjectOperand()); 4647 __ mov(eax, GlobalObjectOperand());
4651 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 4648 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
4652 4649
4653 // Load the function from the receiver. 4650 // Load the function from the receiver.
4654 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 4651 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
4655 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name())); 4652 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
4656 __ mov(LoadDescriptor::SlotRegister(), 4653 __ mov(LoadDescriptor::SlotRegister(),
4657 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); 4654 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
4658 CallLoadIC(NOT_CONTEXTUAL); 4655 CallLoadIC(INSIDE_TYPEOF);
4659 } 4656 }
4660 4657
4661 4658
4662 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 4659 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
4663 ZoneList<Expression*>* args = expr->arguments(); 4660 ZoneList<Expression*>* args = expr->arguments();
4664 int arg_count = args->length(); 4661 int arg_count = args->length();
4665 4662
4666 SetExpressionPosition(expr); 4663 SetExpressionPosition(expr);
4667 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4664 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
4668 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 4665 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
5461 Assembler::target_address_at(call_target_address, 5458 Assembler::target_address_at(call_target_address,
5462 unoptimized_code)); 5459 unoptimized_code));
5463 return OSR_AFTER_STACK_CHECK; 5460 return OSR_AFTER_STACK_CHECK;
5464 } 5461 }
5465 5462
5466 5463
5467 } // namespace internal 5464 } // namespace internal
5468 } // namespace v8 5465 } // namespace v8
5469 5466
5470 #endif // V8_TARGET_ARCH_IA32 5467 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | src/ic/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698