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

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

Issue 2615033002: [fullcodegen] Remove dead hole check logic (Closed)
Patch Set: x87 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
« no previous file with comments | « src/full-codegen/x64/full-codegen-x64.cc ('k') | no next file » | 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 // 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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 __ cmp(ebx, isolate()->factory()->catch_context_map()); 693 __ cmp(ebx, isolate()->factory()->catch_context_map());
694 __ Check(not_equal, kDeclarationInCatchContext); 694 __ Check(not_equal, kDeclarationInCatchContext);
695 } 695 }
696 } 696 }
697 697
698 698
699 void FullCodeGenerator::VisitVariableDeclaration( 699 void FullCodeGenerator::VisitVariableDeclaration(
700 VariableDeclaration* declaration) { 700 VariableDeclaration* declaration) {
701 VariableProxy* proxy = declaration->proxy(); 701 VariableProxy* proxy = declaration->proxy();
702 Variable* variable = proxy->var(); 702 Variable* variable = proxy->var();
703 DCHECK(!variable->binding_needs_init());
703 switch (variable->location()) { 704 switch (variable->location()) {
704 case VariableLocation::UNALLOCATED: { 705 case VariableLocation::UNALLOCATED: {
705 DCHECK(!variable->binding_needs_init());
706 globals_->Add(variable->name(), zone()); 706 globals_->Add(variable->name(), zone());
707 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); 707 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
708 DCHECK(!slot.IsInvalid()); 708 DCHECK(!slot.IsInvalid());
709 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 709 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
710 globals_->Add(isolate()->factory()->undefined_value(), zone()); 710 globals_->Add(isolate()->factory()->undefined_value(), zone());
711 break; 711 break;
712 } 712 }
713 case VariableLocation::PARAMETER: 713 case VariableLocation::PARAMETER:
714 case VariableLocation::LOCAL: 714 case VariableLocation::LOCAL:
715 if (variable->binding_needs_init()) {
716 Comment cmnt(masm_, "[ VariableDeclaration");
717 __ mov(StackOperand(variable),
718 Immediate(isolate()->factory()->the_hole_value()));
719 }
720 break;
721
722 case VariableLocation::CONTEXT: 715 case VariableLocation::CONTEXT:
723 if (variable->binding_needs_init()) {
724 Comment cmnt(masm_, "[ VariableDeclaration");
725 EmitDebugCheckDeclarationContext(variable);
726 __ mov(ContextOperand(esi, variable->index()),
727 Immediate(isolate()->factory()->the_hole_value()));
728 // No write barrier since the hole value is in old space.
729 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
730 }
731 break; 716 break;
732 717
733 case VariableLocation::LOOKUP: 718 case VariableLocation::LOOKUP:
734 case VariableLocation::MODULE: 719 case VariableLocation::MODULE:
735 UNREACHABLE(); 720 UNREACHABLE();
736 } 721 }
737 } 722 }
738 723
739 void FullCodeGenerator::VisitFunctionDeclaration( 724 void FullCodeGenerator::VisitFunctionDeclaration(
740 FunctionDeclaration* declaration) { 725 FunctionDeclaration* declaration) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 __ mov(StoreDescriptor::ReceiverRegister(), eax); 1044 __ mov(StoreDescriptor::ReceiverRegister(), eax);
1060 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); 1045 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize));
1061 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1046 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1062 } 1047 }
1063 1048
1064 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1049 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1065 TypeofMode typeof_mode) { 1050 TypeofMode typeof_mode) {
1066 SetExpressionPosition(proxy); 1051 SetExpressionPosition(proxy);
1067 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1052 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1068 Variable* var = proxy->var(); 1053 Variable* var = proxy->var();
1054 DCHECK(!var->binding_needs_init());
1069 1055
1070 // Two cases: global variables and all other types of variables. 1056 // Two cases: global variables and all other types of variables.
1071 switch (var->location()) { 1057 switch (var->location()) {
1072 case VariableLocation::UNALLOCATED: { 1058 case VariableLocation::UNALLOCATED: {
1073 Comment cmnt(masm_, "[ Global variable"); 1059 Comment cmnt(masm_, "[ Global variable");
1074 EmitGlobalVariableLoad(proxy, typeof_mode); 1060 EmitGlobalVariableLoad(proxy, typeof_mode);
1075 context()->Plug(eax); 1061 context()->Plug(eax);
1076 break; 1062 break;
1077 } 1063 }
1078 1064
1079 case VariableLocation::PARAMETER: 1065 case VariableLocation::PARAMETER:
1080 case VariableLocation::LOCAL: 1066 case VariableLocation::LOCAL:
1081 case VariableLocation::CONTEXT: { 1067 case VariableLocation::CONTEXT: {
1082 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); 1068 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1083 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1069 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1084 : "[ Stack variable"); 1070 : "[ Stack variable");
1085
1086 if (proxy->hole_check_mode() == HoleCheckMode::kRequired) {
1087 // Throw a reference error when using an uninitialized let/const
1088 // binding in harmony mode.
1089 Label done;
1090 GetVar(eax, var);
1091 __ cmp(eax, isolate()->factory()->the_hole_value());
1092 __ j(not_equal, &done, Label::kNear);
1093 __ push(Immediate(var->name()));
1094 __ CallRuntime(Runtime::kThrowReferenceError);
1095 __ bind(&done);
1096 context()->Plug(eax);
1097 break;
1098 }
1099 context()->Plug(var); 1071 context()->Plug(var);
1100 break; 1072 break;
1101 } 1073 }
1102 1074
1103 case VariableLocation::LOOKUP: 1075 case VariableLocation::LOOKUP:
1104 case VariableLocation::MODULE: 1076 case VariableLocation::MODULE:
1105 UNREACHABLE(); 1077 UNREACHABLE();
1106 } 1078 }
1107 } 1079 }
1108 1080
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 } else { 1375 } else {
1404 VisitForAccumulatorValue(expr->value()); 1376 VisitForAccumulatorValue(expr->value());
1405 } 1377 }
1406 1378
1407 SetExpressionPosition(expr); 1379 SetExpressionPosition(expr);
1408 1380
1409 // Store the value. 1381 // Store the value.
1410 switch (assign_type) { 1382 switch (assign_type) {
1411 case VARIABLE: { 1383 case VARIABLE: {
1412 VariableProxy* proxy = expr->target()->AsVariableProxy(); 1384 VariableProxy* proxy = expr->target()->AsVariableProxy();
1413 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), 1385 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot());
1414 proxy->hole_check_mode());
1415 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 1386 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1416 context()->Plug(eax); 1387 context()->Plug(eax);
1417 break; 1388 break;
1418 } 1389 }
1419 case NAMED_PROPERTY: 1390 case NAMED_PROPERTY:
1420 EmitNamedPropertyAssignment(expr); 1391 EmitNamedPropertyAssignment(expr);
1421 break; 1392 break;
1422 case KEYED_PROPERTY: 1393 case KEYED_PROPERTY:
1423 EmitKeyedPropertyAssignment(expr); 1394 EmitKeyedPropertyAssignment(expr);
1424 break; 1395 break;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 FeedbackVectorSlot slot) { 1556 FeedbackVectorSlot slot) {
1586 DCHECK(expr->IsValidReferenceExpressionOrThis()); 1557 DCHECK(expr->IsValidReferenceExpressionOrThis());
1587 1558
1588 Property* prop = expr->AsProperty(); 1559 Property* prop = expr->AsProperty();
1589 LhsKind assign_type = Property::GetAssignType(prop); 1560 LhsKind assign_type = Property::GetAssignType(prop);
1590 1561
1591 switch (assign_type) { 1562 switch (assign_type) {
1592 case VARIABLE: { 1563 case VARIABLE: {
1593 VariableProxy* proxy = expr->AsVariableProxy(); 1564 VariableProxy* proxy = expr->AsVariableProxy();
1594 EffectContext context(this); 1565 EffectContext context(this);
1595 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot, 1566 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot);
1596 proxy->hole_check_mode());
1597 break; 1567 break;
1598 } 1568 }
1599 case NAMED_PROPERTY: { 1569 case NAMED_PROPERTY: {
1600 PushOperand(eax); // Preserve value. 1570 PushOperand(eax); // Preserve value.
1601 VisitForAccumulatorValue(prop->obj()); 1571 VisitForAccumulatorValue(prop->obj());
1602 __ Move(StoreDescriptor::ReceiverRegister(), eax); 1572 __ Move(StoreDescriptor::ReceiverRegister(), eax);
1603 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. 1573 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
1604 CallStoreIC(slot, prop->key()->AsLiteral()->value()); 1574 CallStoreIC(slot, prop->key()->AsLiteral()->value());
1605 break; 1575 break;
1606 } 1576 }
(...skipping 20 matching lines...) Expand all
1627 Variable* var, MemOperand location) { 1597 Variable* var, MemOperand location) {
1628 __ mov(location, eax); 1598 __ mov(location, eax);
1629 if (var->IsContextSlot()) { 1599 if (var->IsContextSlot()) {
1630 __ mov(edx, eax); 1600 __ mov(edx, eax);
1631 int offset = Context::SlotOffset(var->index()); 1601 int offset = Context::SlotOffset(var->index());
1632 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 1602 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
1633 } 1603 }
1634 } 1604 }
1635 1605
1636 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, 1606 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
1637 FeedbackVectorSlot slot, 1607 FeedbackVectorSlot slot) {
1638 HoleCheckMode hole_check_mode) { 1608 DCHECK(!var->binding_needs_init());
1639 if (var->IsUnallocated()) { 1609 if (var->IsUnallocated()) {
1640 // Global var, const, or let. 1610 // Global var, const, or let.
1641 __ mov(StoreDescriptor::ReceiverRegister(), NativeContextOperand()); 1611 __ mov(StoreDescriptor::ReceiverRegister(), NativeContextOperand());
1642 __ mov(StoreDescriptor::ReceiverRegister(), 1612 __ mov(StoreDescriptor::ReceiverRegister(),
1643 ContextOperand(StoreDescriptor::ReceiverRegister(), 1613 ContextOperand(StoreDescriptor::ReceiverRegister(),
1644 Context::EXTENSION_INDEX)); 1614 Context::EXTENSION_INDEX));
1645 CallStoreIC(slot, var->name()); 1615 CallStoreIC(slot, var->name());
1646 1616
1647 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { 1617 } else if (var->mode() == CONST && op != Token::INIT) {
1648 DCHECK(!var->IsLookupSlot()); 1618 if (var->throw_on_const_assignment(language_mode())) {
1649 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1650 MemOperand location = VarOperand(var, ecx);
1651 // Perform an initialization check for lexically declared variables.
1652 if (hole_check_mode == HoleCheckMode::kRequired) {
1653 Label assign;
1654 __ mov(edx, location);
1655 __ cmp(edx, isolate()->factory()->the_hole_value());
1656 __ j(not_equal, &assign, Label::kNear);
1657 __ push(Immediate(var->name()));
1658 __ CallRuntime(Runtime::kThrowReferenceError);
1659 __ bind(&assign);
1660 }
1661 if (var->mode() != CONST) {
1662 EmitStoreToStackLocalOrContextSlot(var, location);
1663 } else if (var->throw_on_const_assignment(language_mode())) {
1664 __ CallRuntime(Runtime::kThrowConstAssignError); 1619 __ CallRuntime(Runtime::kThrowConstAssignError);
1665 } 1620 }
1666 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
1667 // Initializing assignment to const {this} needs a write barrier.
1668 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1669 Label uninitialized_this;
1670 MemOperand location = VarOperand(var, ecx);
1671 __ mov(edx, location);
1672 __ cmp(edx, isolate()->factory()->the_hole_value());
1673 __ j(equal, &uninitialized_this);
1674 __ push(Immediate(var->name()));
1675 __ CallRuntime(Runtime::kThrowReferenceError);
1676 __ bind(&uninitialized_this);
1677 EmitStoreToStackLocalOrContextSlot(var, location);
1678
1679 } else { 1621 } else {
1680 DCHECK(var->mode() != CONST || op == Token::INIT); 1622 DCHECK(!var->is_this());
1681 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 1623 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1682 DCHECK(!var->IsLookupSlot()); 1624 DCHECK(!var->IsLookupSlot());
1683 // Assignment to var or initializing assignment to let/const in harmony
1684 // mode.
1685 MemOperand location = VarOperand(var, ecx); 1625 MemOperand location = VarOperand(var, ecx);
1686 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
1687 // Check for an uninitialized let binding.
1688 __ mov(edx, location);
1689 __ cmp(edx, isolate()->factory()->the_hole_value());
1690 __ Check(equal, kLetBindingReInitialization);
1691 }
1692 EmitStoreToStackLocalOrContextSlot(var, location); 1626 EmitStoreToStackLocalOrContextSlot(var, location);
1693 } 1627 }
1694 } 1628 }
1695 1629
1696 1630
1697 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1631 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1698 // Assignment to a property, using a named store IC. 1632 // Assignment to a property, using a named store IC.
1699 // eax : value 1633 // eax : value
1700 // esp[0] : receiver 1634 // esp[0] : receiver
1701 Property* prop = expr->target()->AsProperty(); 1635 Property* prop = expr->target()->AsProperty();
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 patch_site.EmitPatchInfo(); 2357 patch_site.EmitPatchInfo();
2424 __ bind(&done); 2358 __ bind(&done);
2425 2359
2426 // Store the value returned in eax. 2360 // Store the value returned in eax.
2427 switch (assign_type) { 2361 switch (assign_type) {
2428 case VARIABLE: { 2362 case VARIABLE: {
2429 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2363 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2430 if (expr->is_postfix()) { 2364 if (expr->is_postfix()) {
2431 // Perform the assignment as if via '='. 2365 // Perform the assignment as if via '='.
2432 { EffectContext context(this); 2366 { EffectContext context(this);
2433 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), 2367 EmitVariableAssignment(proxy->var(), Token::ASSIGN,
2434 proxy->hole_check_mode()); 2368 expr->CountSlot());
2435 PrepareForBailoutForId(expr->AssignmentId(), 2369 PrepareForBailoutForId(expr->AssignmentId(),
2436 BailoutState::TOS_REGISTER); 2370 BailoutState::TOS_REGISTER);
2437 context.Plug(eax); 2371 context.Plug(eax);
2438 } 2372 }
2439 // For all contexts except EffectContext We have the result on 2373 // For all contexts except EffectContext We have the result on
2440 // top of the stack. 2374 // top of the stack.
2441 if (!context()->IsEffect()) { 2375 if (!context()->IsEffect()) {
2442 context()->PlugTOS(); 2376 context()->PlugTOS();
2443 } 2377 }
2444 } else { 2378 } else {
2445 // Perform the assignment as if via '='. 2379 // Perform the assignment as if via '='.
2446 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), 2380 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot());
2447 proxy->hole_check_mode());
2448 PrepareForBailoutForId(expr->AssignmentId(), 2381 PrepareForBailoutForId(expr->AssignmentId(),
2449 BailoutState::TOS_REGISTER); 2382 BailoutState::TOS_REGISTER);
2450 context()->Plug(eax); 2383 context()->Plug(eax);
2451 } 2384 }
2452 break; 2385 break;
2453 } 2386 }
2454 case NAMED_PROPERTY: { 2387 case NAMED_PROPERTY: {
2455 PopOperand(StoreDescriptor::ReceiverRegister()); 2388 PopOperand(StoreDescriptor::ReceiverRegister());
2456 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); 2389 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value());
2457 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 2390 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
2786 isolate->builtins()->OnStackReplacement()->entry(), 2719 isolate->builtins()->OnStackReplacement()->entry(),
2787 Assembler::target_address_at(call_target_address, unoptimized_code)); 2720 Assembler::target_address_at(call_target_address, unoptimized_code));
2788 return ON_STACK_REPLACEMENT; 2721 return ON_STACK_REPLACEMENT;
2789 } 2722 }
2790 2723
2791 2724
2792 } // namespace internal 2725 } // namespace internal
2793 } // namespace v8 2726 } // namespace v8
2794 2727
2795 #endif // V8_TARGET_ARCH_X87 2728 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x64/full-codegen-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698