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

Side by Side Diff: src/x87/full-codegen-x87.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_X87 7 #if V8_TARGET_ARCH_X87
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 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 Immediate(isolate()->factory()->home_object_symbol())); 1283 Immediate(isolate()->factory()->home_object_symbol()));
1284 __ mov(StoreDescriptor::ValueRegister(), 1284 __ mov(StoreDescriptor::ValueRegister(),
1285 Operand(esp, offset * kPointerSize)); 1285 Operand(esp, offset * kPointerSize));
1286 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); 1286 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1287 CallStoreIC(); 1287 CallStoreIC();
1288 } 1288 }
1289 } 1289 }
1290 1290
1291 1291
1292 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1292 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1293 TypeofState typeof_state, 1293 TypeofMode typeof_mode,
1294 Label* slow) { 1294 Label* slow) {
1295 Register context = esi; 1295 Register context = esi;
1296 Register temp = edx; 1296 Register temp = edx;
1297 1297
1298 Scope* s = scope(); 1298 Scope* s = scope();
1299 while (s != NULL) { 1299 while (s != NULL) {
1300 if (s->num_heap_slots() > 0) { 1300 if (s->num_heap_slots() > 0) {
1301 if (s->calls_sloppy_eval()) { 1301 if (s->calls_sloppy_eval()) {
1302 // Check that extension is NULL. 1302 // Check that extension is NULL.
1303 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), 1303 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX),
(...skipping 28 matching lines...) Expand all
1332 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1332 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
1333 __ j(not_equal, slow); 1333 __ j(not_equal, slow);
1334 // Load next context in chain. 1334 // Load next context in chain.
1335 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 1335 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
1336 __ jmp(&next); 1336 __ jmp(&next);
1337 __ bind(&fast); 1337 __ bind(&fast);
1338 } 1338 }
1339 1339
1340 // All extension objects were empty and it is safe to use a normal global 1340 // All extension objects were empty and it is safe to use a normal global
1341 // load machinery. 1341 // load machinery.
1342 EmitGlobalVariableLoad(proxy, typeof_state); 1342 EmitGlobalVariableLoad(proxy, typeof_mode);
1343 } 1343 }
1344 1344
1345 1345
1346 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1346 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1347 Label* slow) { 1347 Label* slow) {
1348 DCHECK(var->IsContextSlot()); 1348 DCHECK(var->IsContextSlot());
1349 Register context = esi; 1349 Register context = esi;
1350 Register temp = ebx; 1350 Register temp = ebx;
1351 1351
1352 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1352 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
(...skipping 14 matching lines...) Expand all
1367 __ j(not_equal, slow); 1367 __ j(not_equal, slow);
1368 1368
1369 // This function is used only for loads, not stores, so it's safe to 1369 // This function is used only for loads, not stores, so it's safe to
1370 // return an esi-based operand (the write barrier cannot be allowed to 1370 // return an esi-based operand (the write barrier cannot be allowed to
1371 // destroy the esi register). 1371 // destroy the esi register).
1372 return ContextOperand(context, var->index()); 1372 return ContextOperand(context, var->index());
1373 } 1373 }
1374 1374
1375 1375
1376 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, 1376 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1377 TypeofState typeof_state, 1377 TypeofMode typeof_mode,
1378 Label* slow, 1378 Label* slow, Label* done) {
1379 Label* done) {
1380 // Generate fast-case code for variables that might be shadowed by 1379 // Generate fast-case code for variables that might be shadowed by
1381 // eval-introduced variables. Eval is used a lot without 1380 // eval-introduced variables. Eval is used a lot without
1382 // introducing variables. In those cases, we do not want to 1381 // introducing variables. In those cases, we do not want to
1383 // perform a runtime call for all variables in the scope 1382 // perform a runtime call for all variables in the scope
1384 // containing the eval. 1383 // containing the eval.
1385 Variable* var = proxy->var(); 1384 Variable* var = proxy->var();
1386 if (var->mode() == DYNAMIC_GLOBAL) { 1385 if (var->mode() == DYNAMIC_GLOBAL) {
1387 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); 1386 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1388 __ jmp(done); 1387 __ jmp(done);
1389 } else if (var->mode() == DYNAMIC_LOCAL) { 1388 } else if (var->mode() == DYNAMIC_LOCAL) {
1390 Variable* local = var->local_if_not_shadowed(); 1389 Variable* local = var->local_if_not_shadowed();
1391 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); 1390 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
1392 if (local->mode() == LET || local->mode() == CONST || 1391 if (local->mode() == LET || local->mode() == CONST ||
1393 local->mode() == CONST_LEGACY) { 1392 local->mode() == CONST_LEGACY) {
1394 __ cmp(eax, isolate()->factory()->the_hole_value()); 1393 __ cmp(eax, isolate()->factory()->the_hole_value());
1395 __ j(not_equal, done); 1394 __ j(not_equal, done);
1396 if (local->mode() == CONST_LEGACY) { 1395 if (local->mode() == CONST_LEGACY) {
1397 __ mov(eax, isolate()->factory()->undefined_value()); 1396 __ mov(eax, isolate()->factory()->undefined_value());
1398 } else { // LET || CONST 1397 } else { // LET || CONST
1399 __ push(Immediate(var->name())); 1398 __ push(Immediate(var->name()));
1400 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1399 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1401 } 1400 }
1402 } 1401 }
1403 __ jmp(done); 1402 __ jmp(done);
1404 } 1403 }
1405 } 1404 }
1406 1405
1407 1406
1408 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1407 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1409 TypeofState typeof_state) { 1408 TypeofMode typeof_mode) {
1410 Variable* var = proxy->var(); 1409 Variable* var = proxy->var();
1411 DCHECK(var->IsUnallocatedOrGlobalSlot() || 1410 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1412 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); 1411 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1413 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1412 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1414 __ mov(LoadDescriptor::NameRegister(), var->name()); 1413 __ mov(LoadDescriptor::NameRegister(), var->name());
1415 __ mov(LoadDescriptor::SlotRegister(), 1414 __ mov(LoadDescriptor::SlotRegister(),
1416 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1415 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
1417 // Inside typeof use a regular load, not a contextual load, to avoid 1416 CallLoadIC(typeof_mode);
1418 // a reference error.
1419 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
1420 } 1417 }
1421 1418
1422 1419
1423 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1420 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1424 TypeofState typeof_state) { 1421 TypeofMode typeof_mode) {
1425 SetExpressionPosition(proxy); 1422 SetExpressionPosition(proxy);
1426 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1423 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1427 Variable* var = proxy->var(); 1424 Variable* var = proxy->var();
1428 1425
1429 // Three cases: global variables, lookup variables, and all other types of 1426 // Three cases: global variables, lookup variables, and all other types of
1430 // variables. 1427 // variables.
1431 switch (var->location()) { 1428 switch (var->location()) {
1432 case VariableLocation::GLOBAL: 1429 case VariableLocation::GLOBAL:
1433 case VariableLocation::UNALLOCATED: { 1430 case VariableLocation::UNALLOCATED: {
1434 Comment cmnt(masm_, "[ Global variable"); 1431 Comment cmnt(masm_, "[ Global variable");
1435 EmitGlobalVariableLoad(proxy, typeof_state); 1432 EmitGlobalVariableLoad(proxy, typeof_mode);
1436 context()->Plug(eax); 1433 context()->Plug(eax);
1437 break; 1434 break;
1438 } 1435 }
1439 1436
1440 case VariableLocation::PARAMETER: 1437 case VariableLocation::PARAMETER:
1441 case VariableLocation::LOCAL: 1438 case VariableLocation::LOCAL:
1442 case VariableLocation::CONTEXT: { 1439 case VariableLocation::CONTEXT: {
1443 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); 1440 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1444 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1441 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1445 : "[ Stack variable"); 1442 : "[ Stack variable");
1446 if (var->binding_needs_init()) { 1443 if (var->binding_needs_init()) {
1447 // var->scope() may be NULL when the proxy is located in eval code and 1444 // var->scope() may be NULL when the proxy is located in eval code and
1448 // refers to a potential outside binding. Currently those bindings are 1445 // refers to a potential outside binding. Currently those bindings are
1449 // always looked up dynamically, i.e. in that case 1446 // always looked up dynamically, i.e. in that case
1450 // var->location() == LOOKUP. 1447 // var->location() == LOOKUP.
1451 // always holds. 1448 // always holds.
1452 DCHECK(var->scope() != NULL); 1449 DCHECK(var->scope() != NULL);
1453 1450
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 } 1503 }
1507 context()->Plug(var); 1504 context()->Plug(var);
1508 break; 1505 break;
1509 } 1506 }
1510 1507
1511 case VariableLocation::LOOKUP: { 1508 case VariableLocation::LOOKUP: {
1512 Comment cmnt(masm_, "[ Lookup variable"); 1509 Comment cmnt(masm_, "[ Lookup variable");
1513 Label done, slow; 1510 Label done, slow;
1514 // Generate code for loading from variables potentially shadowed 1511 // Generate code for loading from variables potentially shadowed
1515 // by eval-introduced variables. 1512 // by eval-introduced variables.
1516 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); 1513 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1517 __ bind(&slow); 1514 __ bind(&slow);
1518 __ push(esi); // Context. 1515 __ push(esi); // Context.
1519 __ push(Immediate(var->name())); 1516 __ push(Immediate(var->name()));
1520 Runtime::FunctionId function_id = 1517 Runtime::FunctionId function_id =
1521 typeof_state == NOT_INSIDE_TYPEOF 1518 typeof_mode == NOT_INSIDE_TYPEOF
1522 ? Runtime::kLoadLookupSlot 1519 ? Runtime::kLoadLookupSlot
1523 : Runtime::kLoadLookupSlotNoReferenceError; 1520 : Runtime::kLoadLookupSlotNoReferenceError;
1524 __ CallRuntime(function_id, 2); 1521 __ CallRuntime(function_id, 2);
1525 __ bind(&done); 1522 __ bind(&done);
1526 context()->Plug(eax); 1523 context()->Plug(eax);
1527 break; 1524 break;
1528 } 1525 }
1529 } 1526 }
1530 } 1527 }
1531 1528
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
2192 __ Drop(1); // The function is still on the stack; drop it. 2189 __ Drop(1); // The function is still on the stack; drop it.
2193 2190
2194 // if (!result.done) goto l_try; 2191 // if (!result.done) goto l_try;
2195 __ bind(&l_loop); 2192 __ bind(&l_loop);
2196 __ push(eax); // save result 2193 __ push(eax); // save result
2197 __ Move(load_receiver, eax); // result 2194 __ Move(load_receiver, eax); // result
2198 __ mov(load_name, 2195 __ mov(load_name,
2199 isolate()->factory()->done_string()); // "done" 2196 isolate()->factory()->done_string()); // "done"
2200 __ mov(LoadDescriptor::SlotRegister(), 2197 __ mov(LoadDescriptor::SlotRegister(),
2201 Immediate(SmiFromSlot(expr->DoneFeedbackSlot()))); 2198 Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
2202 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax 2199 CallLoadIC(INSIDE_TYPEOF); // result.done in eax
2203 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2200 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2204 CallIC(bool_ic); 2201 CallIC(bool_ic);
2205 __ test(eax, eax); 2202 __ test(eax, eax);
2206 __ j(zero, &l_try); 2203 __ j(zero, &l_try);
2207 2204
2208 // result.value 2205 // result.value
2209 __ pop(load_receiver); // result 2206 __ pop(load_receiver); // result
2210 __ mov(load_name, 2207 __ mov(load_name,
2211 isolate()->factory()->value_string()); // "value" 2208 isolate()->factory()->value_string()); // "value"
2212 __ mov(LoadDescriptor::SlotRegister(), 2209 __ mov(LoadDescriptor::SlotRegister(),
2213 Immediate(SmiFromSlot(expr->ValueFeedbackSlot()))); 2210 Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
2214 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax 2211 CallLoadIC(INSIDE_TYPEOF); // result.value in eax
2215 context()->DropAndPlug(2, eax); // drop iter and g 2212 context()->DropAndPlug(2, eax); // drop iter and g
2216 break; 2213 break;
2217 } 2214 }
2218 } 2215 }
2219 } 2216 }
2220 2217
2221 2218
2222 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2219 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2223 Expression *value, 2220 Expression *value,
2224 JSGeneratorObject::ResumeMode resume_mode) { 2221 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2343 2340
2344 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2341 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2345 SetExpressionPosition(prop); 2342 SetExpressionPosition(prop);
2346 Literal* key = prop->key()->AsLiteral(); 2343 Literal* key = prop->key()->AsLiteral();
2347 DCHECK(!key->value()->IsSmi()); 2344 DCHECK(!key->value()->IsSmi());
2348 DCHECK(!prop->IsSuperAccess()); 2345 DCHECK(!prop->IsSuperAccess());
2349 2346
2350 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); 2347 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
2351 __ mov(LoadDescriptor::SlotRegister(), 2348 __ mov(LoadDescriptor::SlotRegister(),
2352 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2349 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
2353 CallLoadIC(NOT_CONTEXTUAL, language_mode()); 2350 CallLoadIC(INSIDE_TYPEOF, language_mode());
2354 } 2351 }
2355 2352
2356 2353
2357 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2354 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2358 // Stack: receiver, home_object. 2355 // Stack: receiver, home_object.
2359 SetExpressionPosition(prop); 2356 SetExpressionPosition(prop);
2360 Literal* key = prop->key()->AsLiteral(); 2357 Literal* key = prop->key()->AsLiteral();
2361 DCHECK(!key->value()->IsSmi()); 2358 DCHECK(!key->value()->IsSmi());
2362 DCHECK(prop->IsSuperAccess()); 2359 DCHECK(prop->IsSuperAccess());
2363 2360
(...skipping 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after
4638 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 4635 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4639 // Push the builtins object as receiver. 4636 // Push the builtins object as receiver.
4640 __ mov(eax, GlobalObjectOperand()); 4637 __ mov(eax, GlobalObjectOperand());
4641 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 4638 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
4642 4639
4643 // Load the function from the receiver. 4640 // Load the function from the receiver.
4644 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 4641 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
4645 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name())); 4642 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
4646 __ mov(LoadDescriptor::SlotRegister(), 4643 __ mov(LoadDescriptor::SlotRegister(),
4647 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); 4644 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
4648 CallLoadIC(NOT_CONTEXTUAL); 4645 CallLoadIC(INSIDE_TYPEOF);
4649 } 4646 }
4650 4647
4651 4648
4652 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 4649 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
4653 ZoneList<Expression*>* args = expr->arguments(); 4650 ZoneList<Expression*>* args = expr->arguments();
4654 int arg_count = args->length(); 4651 int arg_count = args->length();
4655 4652
4656 SetExpressionPosition(expr); 4653 SetExpressionPosition(expr);
4657 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4654 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
4658 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 4655 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
5451 Assembler::target_address_at(call_target_address, 5448 Assembler::target_address_at(call_target_address,
5452 unoptimized_code)); 5449 unoptimized_code));
5453 return OSR_AFTER_STACK_CHECK; 5450 return OSR_AFTER_STACK_CHECK;
5454 } 5451 }
5455 5452
5456 5453
5457 } // namespace internal 5454 } // namespace internal
5458 } // namespace v8 5455 } // namespace v8
5459 5456
5460 #endif // V8_TARGET_ARCH_X87 5457 #endif // V8_TARGET_ARCH_X87
OLDNEW
« src/ic/ic.cc ('K') | « src/x64/lithium-x64.h ('k') | src/x87/lithium-codegen-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698