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

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

Issue 2640793004: Revert remove dead hole check logic (Closed)
Patch Set: Revert "[crankshaft] Fix mips/mips64 build: remove unused variable" and "[crankshaft] Remove dead Variable hole-checking code" Created 3 years, 11 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 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/ast/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/builtins/builtins-constructor.h" 9 #include "src/builtins/builtins-constructor.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 __ cmp(ebx, isolate()->factory()->catch_context_map()); 691 __ cmp(ebx, isolate()->factory()->catch_context_map());
692 __ Check(not_equal, kDeclarationInCatchContext); 692 __ Check(not_equal, kDeclarationInCatchContext);
693 } 693 }
694 } 694 }
695 695
696 696
697 void FullCodeGenerator::VisitVariableDeclaration( 697 void FullCodeGenerator::VisitVariableDeclaration(
698 VariableDeclaration* declaration) { 698 VariableDeclaration* declaration) {
699 VariableProxy* proxy = declaration->proxy(); 699 VariableProxy* proxy = declaration->proxy();
700 Variable* variable = proxy->var(); 700 Variable* variable = proxy->var();
701 DCHECK(!variable->binding_needs_init());
702 switch (variable->location()) { 701 switch (variable->location()) {
703 case VariableLocation::UNALLOCATED: { 702 case VariableLocation::UNALLOCATED: {
703 DCHECK(!variable->binding_needs_init());
704 globals_->Add(variable->name(), zone()); 704 globals_->Add(variable->name(), zone());
705 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); 705 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
706 DCHECK(!slot.IsInvalid()); 706 DCHECK(!slot.IsInvalid());
707 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 707 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
708 globals_->Add(isolate()->factory()->undefined_value(), zone()); 708 globals_->Add(isolate()->factory()->undefined_value(), zone());
709 break; 709 break;
710 } 710 }
711 case VariableLocation::PARAMETER: 711 case VariableLocation::PARAMETER:
712 case VariableLocation::LOCAL: 712 case VariableLocation::LOCAL:
713 if (variable->binding_needs_init()) {
714 Comment cmnt(masm_, "[ VariableDeclaration");
715 __ mov(StackOperand(variable),
716 Immediate(isolate()->factory()->the_hole_value()));
717 }
718 break;
719
713 case VariableLocation::CONTEXT: 720 case VariableLocation::CONTEXT:
721 if (variable->binding_needs_init()) {
722 Comment cmnt(masm_, "[ VariableDeclaration");
723 EmitDebugCheckDeclarationContext(variable);
724 __ mov(ContextOperand(esi, variable->index()),
725 Immediate(isolate()->factory()->the_hole_value()));
726 // No write barrier since the hole value is in old space.
727 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
728 }
714 break; 729 break;
715 730
716 case VariableLocation::LOOKUP: 731 case VariableLocation::LOOKUP:
717 case VariableLocation::MODULE: 732 case VariableLocation::MODULE:
718 UNREACHABLE(); 733 UNREACHABLE();
719 } 734 }
720 } 735 }
721 736
722 void FullCodeGenerator::VisitFunctionDeclaration( 737 void FullCodeGenerator::VisitFunctionDeclaration(
723 FunctionDeclaration* declaration) { 738 FunctionDeclaration* declaration) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 __ mov(StoreDescriptor::ReceiverRegister(), eax); 1057 __ mov(StoreDescriptor::ReceiverRegister(), eax);
1043 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); 1058 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize));
1044 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1059 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1045 } 1060 }
1046 1061
1047 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1062 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1048 TypeofMode typeof_mode) { 1063 TypeofMode typeof_mode) {
1049 SetExpressionPosition(proxy); 1064 SetExpressionPosition(proxy);
1050 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1065 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1051 Variable* var = proxy->var(); 1066 Variable* var = proxy->var();
1052 DCHECK(!var->binding_needs_init());
1053 1067
1054 // Two cases: global variables and all other types of variables. 1068 // Two cases: global variables and all other types of variables.
1055 switch (var->location()) { 1069 switch (var->location()) {
1056 case VariableLocation::UNALLOCATED: { 1070 case VariableLocation::UNALLOCATED: {
1057 Comment cmnt(masm_, "[ Global variable"); 1071 Comment cmnt(masm_, "[ Global variable");
1058 EmitGlobalVariableLoad(proxy, typeof_mode); 1072 EmitGlobalVariableLoad(proxy, typeof_mode);
1059 context()->Plug(eax); 1073 context()->Plug(eax);
1060 break; 1074 break;
1061 } 1075 }
1062 1076
1063 case VariableLocation::PARAMETER: 1077 case VariableLocation::PARAMETER:
1064 case VariableLocation::LOCAL: 1078 case VariableLocation::LOCAL:
1065 case VariableLocation::CONTEXT: { 1079 case VariableLocation::CONTEXT: {
1066 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); 1080 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1067 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1081 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1068 : "[ Stack variable"); 1082 : "[ Stack variable");
1083
1084 if (proxy->hole_check_mode() == HoleCheckMode::kRequired) {
1085 // Throw a reference error when using an uninitialized let/const
1086 // binding in harmony mode.
1087 Label done;
1088 GetVar(eax, var);
1089 __ cmp(eax, isolate()->factory()->the_hole_value());
1090 __ j(not_equal, &done, Label::kNear);
1091 __ push(Immediate(var->name()));
1092 __ CallRuntime(Runtime::kThrowReferenceError);
1093 __ bind(&done);
1094 context()->Plug(eax);
1095 break;
1096 }
1069 context()->Plug(var); 1097 context()->Plug(var);
1070 break; 1098 break;
1071 } 1099 }
1072 1100
1073 case VariableLocation::LOOKUP: 1101 case VariableLocation::LOOKUP:
1074 case VariableLocation::MODULE: 1102 case VariableLocation::MODULE:
1075 UNREACHABLE(); 1103 UNREACHABLE();
1076 } 1104 }
1077 } 1105 }
1078 1106
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 } else { 1404 } else {
1377 VisitForAccumulatorValue(expr->value()); 1405 VisitForAccumulatorValue(expr->value());
1378 } 1406 }
1379 1407
1380 SetExpressionPosition(expr); 1408 SetExpressionPosition(expr);
1381 1409
1382 // Store the value. 1410 // Store the value.
1383 switch (assign_type) { 1411 switch (assign_type) {
1384 case VARIABLE: { 1412 case VARIABLE: {
1385 VariableProxy* proxy = expr->target()->AsVariableProxy(); 1413 VariableProxy* proxy = expr->target()->AsVariableProxy();
1386 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot()); 1414 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(),
1415 proxy->hole_check_mode());
1387 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 1416 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1388 context()->Plug(eax); 1417 context()->Plug(eax);
1389 break; 1418 break;
1390 } 1419 }
1391 case NAMED_PROPERTY: 1420 case NAMED_PROPERTY:
1392 EmitNamedPropertyAssignment(expr); 1421 EmitNamedPropertyAssignment(expr);
1393 break; 1422 break;
1394 case KEYED_PROPERTY: 1423 case KEYED_PROPERTY:
1395 EmitKeyedPropertyAssignment(expr); 1424 EmitKeyedPropertyAssignment(expr);
1396 break; 1425 break;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 FeedbackVectorSlot slot) { 1586 FeedbackVectorSlot slot) {
1558 DCHECK(expr->IsValidReferenceExpressionOrThis()); 1587 DCHECK(expr->IsValidReferenceExpressionOrThis());
1559 1588
1560 Property* prop = expr->AsProperty(); 1589 Property* prop = expr->AsProperty();
1561 LhsKind assign_type = Property::GetAssignType(prop); 1590 LhsKind assign_type = Property::GetAssignType(prop);
1562 1591
1563 switch (assign_type) { 1592 switch (assign_type) {
1564 case VARIABLE: { 1593 case VARIABLE: {
1565 VariableProxy* proxy = expr->AsVariableProxy(); 1594 VariableProxy* proxy = expr->AsVariableProxy();
1566 EffectContext context(this); 1595 EffectContext context(this);
1567 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot); 1596 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot,
1597 proxy->hole_check_mode());
1568 break; 1598 break;
1569 } 1599 }
1570 case NAMED_PROPERTY: { 1600 case NAMED_PROPERTY: {
1571 PushOperand(eax); // Preserve value. 1601 PushOperand(eax); // Preserve value.
1572 VisitForAccumulatorValue(prop->obj()); 1602 VisitForAccumulatorValue(prop->obj());
1573 __ Move(StoreDescriptor::ReceiverRegister(), eax); 1603 __ Move(StoreDescriptor::ReceiverRegister(), eax);
1574 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. 1604 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
1575 CallStoreIC(slot, prop->key()->AsLiteral()->value()); 1605 CallStoreIC(slot, prop->key()->AsLiteral()->value());
1576 break; 1606 break;
1577 } 1607 }
(...skipping 20 matching lines...) Expand all
1598 Variable* var, MemOperand location) { 1628 Variable* var, MemOperand location) {
1599 __ mov(location, eax); 1629 __ mov(location, eax);
1600 if (var->IsContextSlot()) { 1630 if (var->IsContextSlot()) {
1601 __ mov(edx, eax); 1631 __ mov(edx, eax);
1602 int offset = Context::SlotOffset(var->index()); 1632 int offset = Context::SlotOffset(var->index());
1603 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 1633 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
1604 } 1634 }
1605 } 1635 }
1606 1636
1607 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, 1637 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
1608 FeedbackVectorSlot slot) { 1638 FeedbackVectorSlot slot,
1609 DCHECK(!var->binding_needs_init()); 1639 HoleCheckMode hole_check_mode) {
1610 if (var->IsUnallocated()) { 1640 if (var->IsUnallocated()) {
1611 // Global var, const, or let. 1641 // Global var, const, or let.
1612 __ mov(StoreDescriptor::ReceiverRegister(), NativeContextOperand()); 1642 __ mov(StoreDescriptor::ReceiverRegister(), NativeContextOperand());
1613 __ mov(StoreDescriptor::ReceiverRegister(), 1643 __ mov(StoreDescriptor::ReceiverRegister(),
1614 ContextOperand(StoreDescriptor::ReceiverRegister(), 1644 ContextOperand(StoreDescriptor::ReceiverRegister(),
1615 Context::EXTENSION_INDEX)); 1645 Context::EXTENSION_INDEX));
1616 CallStoreIC(slot, var->name()); 1646 CallStoreIC(slot, var->name());
1617 1647
1618 } else if (var->mode() == CONST && op != Token::INIT) { 1648 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) {
1619 if (var->throw_on_const_assignment(language_mode())) { 1649 DCHECK(!var->IsLookupSlot());
1650 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1651 MemOperand location = VarOperand(var, ecx);
1652 // Perform an initialization check for lexically declared variables.
1653 if (hole_check_mode == HoleCheckMode::kRequired) {
1654 Label assign;
1655 __ mov(edx, location);
1656 __ cmp(edx, isolate()->factory()->the_hole_value());
1657 __ j(not_equal, &assign, Label::kNear);
1658 __ push(Immediate(var->name()));
1659 __ CallRuntime(Runtime::kThrowReferenceError);
1660 __ bind(&assign);
1661 }
1662 if (var->mode() != CONST) {
1663 EmitStoreToStackLocalOrContextSlot(var, location);
1664 } else if (var->throw_on_const_assignment(language_mode())) {
1620 __ CallRuntime(Runtime::kThrowConstAssignError); 1665 __ CallRuntime(Runtime::kThrowConstAssignError);
1621 } 1666 }
1667 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
1668 // Initializing assignment to const {this} needs a write barrier.
1669 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1670 Label uninitialized_this;
1671 MemOperand location = VarOperand(var, ecx);
1672 __ mov(edx, location);
1673 __ cmp(edx, isolate()->factory()->the_hole_value());
1674 __ j(equal, &uninitialized_this);
1675 __ push(Immediate(var->name()));
1676 __ CallRuntime(Runtime::kThrowReferenceError);
1677 __ bind(&uninitialized_this);
1678 EmitStoreToStackLocalOrContextSlot(var, location);
1679
1622 } else { 1680 } else {
1623 DCHECK(!var->is_this()); 1681 DCHECK(var->mode() != CONST || op == Token::INIT);
1624 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 1682 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1625 DCHECK(!var->IsLookupSlot()); 1683 DCHECK(!var->IsLookupSlot());
1684 // Assignment to var or initializing assignment to let/const in harmony
1685 // mode.
1626 MemOperand location = VarOperand(var, ecx); 1686 MemOperand location = VarOperand(var, ecx);
1687 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
1688 // Check for an uninitialized let binding.
1689 __ mov(edx, location);
1690 __ cmp(edx, isolate()->factory()->the_hole_value());
1691 __ Check(equal, kLetBindingReInitialization);
1692 }
1627 EmitStoreToStackLocalOrContextSlot(var, location); 1693 EmitStoreToStackLocalOrContextSlot(var, location);
1628 } 1694 }
1629 } 1695 }
1630 1696
1631 1697
1632 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1698 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1633 // Assignment to a property, using a named store IC. 1699 // Assignment to a property, using a named store IC.
1634 // eax : value 1700 // eax : value
1635 // esp[0] : receiver 1701 // esp[0] : receiver
1636 Property* prop = expr->target()->AsProperty(); 1702 Property* prop = expr->target()->AsProperty();
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
2336 patch_site.EmitPatchInfo(); 2402 patch_site.EmitPatchInfo();
2337 __ bind(&done); 2403 __ bind(&done);
2338 2404
2339 // Store the value returned in eax. 2405 // Store the value returned in eax.
2340 switch (assign_type) { 2406 switch (assign_type) {
2341 case VARIABLE: { 2407 case VARIABLE: {
2342 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2408 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2343 if (expr->is_postfix()) { 2409 if (expr->is_postfix()) {
2344 // Perform the assignment as if via '='. 2410 // Perform the assignment as if via '='.
2345 { EffectContext context(this); 2411 { EffectContext context(this);
2346 EmitVariableAssignment(proxy->var(), Token::ASSIGN, 2412 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(),
2347 expr->CountSlot()); 2413 proxy->hole_check_mode());
2348 PrepareForBailoutForId(expr->AssignmentId(), 2414 PrepareForBailoutForId(expr->AssignmentId(),
2349 BailoutState::TOS_REGISTER); 2415 BailoutState::TOS_REGISTER);
2350 context.Plug(eax); 2416 context.Plug(eax);
2351 } 2417 }
2352 // For all contexts except EffectContext We have the result on 2418 // For all contexts except EffectContext We have the result on
2353 // top of the stack. 2419 // top of the stack.
2354 if (!context()->IsEffect()) { 2420 if (!context()->IsEffect()) {
2355 context()->PlugTOS(); 2421 context()->PlugTOS();
2356 } 2422 }
2357 } else { 2423 } else {
2358 // Perform the assignment as if via '='. 2424 // Perform the assignment as if via '='.
2359 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot()); 2425 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(),
2426 proxy->hole_check_mode());
2360 PrepareForBailoutForId(expr->AssignmentId(), 2427 PrepareForBailoutForId(expr->AssignmentId(),
2361 BailoutState::TOS_REGISTER); 2428 BailoutState::TOS_REGISTER);
2362 context()->Plug(eax); 2429 context()->Plug(eax);
2363 } 2430 }
2364 break; 2431 break;
2365 } 2432 }
2366 case NAMED_PROPERTY: { 2433 case NAMED_PROPERTY: {
2367 PopOperand(StoreDescriptor::ReceiverRegister()); 2434 PopOperand(StoreDescriptor::ReceiverRegister());
2368 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); 2435 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value());
2369 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 2436 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
2698 isolate->builtins()->OnStackReplacement()->entry(), 2765 isolate->builtins()->OnStackReplacement()->entry(),
2699 Assembler::target_address_at(call_target_address, unoptimized_code)); 2766 Assembler::target_address_at(call_target_address, unoptimized_code));
2700 return ON_STACK_REPLACEMENT; 2767 return ON_STACK_REPLACEMENT;
2701 } 2768 }
2702 2769
2703 2770
2704 } // namespace internal 2771 } // namespace internal
2705 } // namespace v8 2772 } // namespace v8
2706 2773
2707 #endif // V8_TARGET_ARCH_X87 2774 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x64/full-codegen-x64.cc ('k') | test/cctest/interpreter/bytecode_expectations/Generators.golden » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698