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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1419003002: [Interpreter] Unify global and unallocated variable access. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 5 years, 2 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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/control-flow-builders.h" 8 #include "src/interpreter/control-flow-builders.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 case ObjectLiteral::Property::CONSTANT: 706 case ObjectLiteral::Property::CONSTANT:
707 UNREACHABLE(); 707 UNREACHABLE();
708 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 708 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
709 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 709 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
710 // Fall through. 710 // Fall through.
711 case ObjectLiteral::Property::COMPUTED: { 711 case ObjectLiteral::Property::COMPUTED: {
712 // It is safe to use [[Put]] here because the boilerplate already 712 // It is safe to use [[Put]] here because the boilerplate already
713 // contains computed properties with an uninitialized value. 713 // contains computed properties with an uninitialized value.
714 if (literal_key->value()->IsInternalizedString()) { 714 if (literal_key->value()->IsInternalizedString()) {
715 if (property->emit_store()) { 715 if (property->emit_store()) {
716 Register name = inner_temporary_register_scope.NewRegister(); 716 size_t name_index =
717 builder() 717 builder()->GetConstantPoolEntry(literal_key->AsPropertyName());
718 ->LoadLiteral(literal_key->AsPropertyName())
719 .StoreAccumulatorInRegister(name);
720 VisitForAccumulatorValue(property->value()); 718 VisitForAccumulatorValue(property->value());
721 builder()->StoreNamedProperty(literal, name, 719 builder()->StoreNamedProperty(literal, name_index,
722 feedback_index(property->GetSlot(0)), 720 feedback_index(property->GetSlot(0)),
723 language_mode()); 721 language_mode());
724 } else { 722 } else {
725 VisitForEffect(property->value()); 723 VisitForEffect(property->value());
726 } 724 }
727 } else { 725 } else {
728 inner_temporary_register_scope.PrepareForConsecutiveAllocations(3); 726 inner_temporary_register_scope.PrepareForConsecutiveAllocations(3);
729 Register key = 727 Register key =
730 inner_temporary_register_scope.NextConsecutiveRegister(); 728 inner_temporary_register_scope.NextConsecutiveRegister();
731 Register value = 729 Register value =
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 } 930 }
933 case VariableLocation::PARAMETER: { 931 case VariableLocation::PARAMETER: {
934 // The parameter indices are shifted by 1 (receiver is variable 932 // The parameter indices are shifted by 1 (receiver is variable
935 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 933 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
936 Register source = builder()->Parameter(variable->index() + 1); 934 Register source = builder()->Parameter(variable->index() + 1);
937 execution_result()->SetResultInRegister(source); 935 execution_result()->SetResultInRegister(source);
938 break; 936 break;
939 } 937 }
940 case VariableLocation::GLOBAL: 938 case VariableLocation::GLOBAL:
941 case VariableLocation::UNALLOCATED: { 939 case VariableLocation::UNALLOCATED: {
942 TemporaryRegisterScope temporary_register_scope(builder()); 940 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
943 Register obj = temporary_register_scope.NewRegister(); 941 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode());
944 builder()->LoadContextSlot(execution_context()->reg(),
945 Context::GLOBAL_OBJECT_INDEX);
946 builder()->StoreAccumulatorInRegister(obj);
947 builder()->LoadLiteral(variable->name());
948 builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode());
949 execution_result()->SetResultInAccumulator(); 942 execution_result()->SetResultInAccumulator();
950 break; 943 break;
951 } 944 }
952 case VariableLocation::CONTEXT: { 945 case VariableLocation::CONTEXT: {
953 ContextScope* context = execution_context()->Previous(variable->scope()); 946 ContextScope* context = execution_context()->Previous(variable->scope());
954 if (context) { 947 if (context) {
955 builder()->LoadContextSlot(context->reg(), variable->index()); 948 builder()->LoadContextSlot(context->reg(), variable->index());
956 execution_result()->SetResultInAccumulator(); 949 execution_result()->SetResultInAccumulator();
957 } else { 950 } else {
958 UNIMPLEMENTED(); 951 UNIMPLEMENTED();
(...skipping 21 matching lines...) Expand all
980 case VariableLocation::PARAMETER: { 973 case VariableLocation::PARAMETER: {
981 // The parameter indices are shifted by 1 (receiver is variable 974 // The parameter indices are shifted by 1 (receiver is variable
982 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 975 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
983 Register destination(builder()->Parameter(variable->index() + 1)); 976 Register destination(builder()->Parameter(variable->index() + 1));
984 builder()->StoreAccumulatorInRegister(destination); 977 builder()->StoreAccumulatorInRegister(destination);
985 RecordStoreToRegister(destination); 978 RecordStoreToRegister(destination);
986 break; 979 break;
987 } 980 }
988 case VariableLocation::GLOBAL: 981 case VariableLocation::GLOBAL:
989 case VariableLocation::UNALLOCATED: { 982 case VariableLocation::UNALLOCATED: {
990 Register value = execution_result()->NewRegister(); 983 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
991 Register obj = execution_result()->NewRegister(); 984 builder()->StoreGlobal(name_index, feedback_index(slot), language_mode());
992 Register name = execution_result()->NewRegister();
993
994 // TODO(rmcilroy): Investigate whether we can avoid having to stash the
995 // value in a register.
996 builder()->StoreAccumulatorInRegister(value);
997 builder()->LoadContextSlot(execution_context()->reg(),
998 Context::GLOBAL_OBJECT_INDEX);
999 builder()->StoreAccumulatorInRegister(obj);
1000 builder()->LoadLiteral(variable->name());
1001 builder()->StoreAccumulatorInRegister(name);
1002 builder()->LoadAccumulatorWithRegister(value);
1003 builder()->StoreNamedProperty(obj, name, feedback_index(slot),
1004 language_mode());
1005 break; 985 break;
1006 } 986 }
1007 case VariableLocation::CONTEXT: { 987 case VariableLocation::CONTEXT: {
1008 // TODO(rmcilroy): support const mode initialization. 988 // TODO(rmcilroy): support const mode initialization.
1009 ContextScope* context = execution_context()->Previous(variable->scope()); 989 ContextScope* context = execution_context()->Previous(variable->scope());
1010 if (context) { 990 if (context) {
1011 builder()->StoreContextSlot(context->reg(), variable->index()); 991 builder()->StoreContextSlot(context->reg(), variable->index());
1012 } else { 992 } else {
1013 UNIMPLEMENTED(); 993 UNIMPLEMENTED();
1014 } 994 }
1015 break; 995 break;
1016 } 996 }
1017 case VariableLocation::LOOKUP: 997 case VariableLocation::LOOKUP:
1018 UNIMPLEMENTED(); 998 UNIMPLEMENTED();
1019 } 999 }
1020 } 1000 }
1021 1001
1022 1002
1023 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 1003 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
1024 DCHECK(expr->target()->IsValidReferenceExpression()); 1004 DCHECK(expr->target()->IsValidReferenceExpression());
1025 Register object, key; 1005 Register object, key;
1006 size_t name_index;
1026 1007
1027 // Left-hand side can only be a property, a global or a variable slot. 1008 // Left-hand side can only be a property, a global or a variable slot.
1028 Property* property = expr->target()->AsProperty(); 1009 Property* property = expr->target()->AsProperty();
1029 LhsKind assign_type = Property::GetAssignType(property); 1010 LhsKind assign_type = Property::GetAssignType(property);
1030 1011
1031 // Evaluate LHS expression. 1012 // Evaluate LHS expression.
1032 switch (assign_type) { 1013 switch (assign_type) {
1033 case VARIABLE: 1014 case VARIABLE:
1034 // Nothing to do to evaluate variable assignment LHS. 1015 // Nothing to do to evaluate variable assignment LHS.
1035 break; 1016 break;
1036 case NAMED_PROPERTY: { 1017 case NAMED_PROPERTY: {
1037 object = VisitForRegisterValue(property->obj()); 1018 object = VisitForRegisterValue(property->obj());
1038 key = execution_result()->NewRegister(); 1019 name_index = builder()->GetConstantPoolEntry(
1039 builder()->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()); 1020 property->key()->AsLiteral()->AsPropertyName());
1040 builder()->StoreAccumulatorInRegister(key);
1041 break; 1021 break;
1042 } 1022 }
1043 case KEYED_PROPERTY: { 1023 case KEYED_PROPERTY: {
1044 object = VisitForRegisterValue(property->obj()); 1024 object = VisitForRegisterValue(property->obj());
1045 key = VisitForRegisterValue(property->key()); 1025 key = VisitForRegisterValue(property->key());
1046 break; 1026 break;
1047 } 1027 }
1048 case NAMED_SUPER_PROPERTY: 1028 case NAMED_SUPER_PROPERTY:
1049 case KEYED_SUPER_PROPERTY: 1029 case KEYED_SUPER_PROPERTY:
1050 UNIMPLEMENTED(); 1030 UNIMPLEMENTED();
(...skipping 11 matching lines...) Expand all
1062 FeedbackVectorSlot slot = expr->AssignmentSlot(); 1042 FeedbackVectorSlot slot = expr->AssignmentSlot();
1063 switch (assign_type) { 1043 switch (assign_type) {
1064 case VARIABLE: { 1044 case VARIABLE: {
1065 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. 1045 // TODO(oth): The VisitVariableAssignment() call is hard to reason about.
1066 // Is the value in the accumulator safe? Yes, but scary. 1046 // Is the value in the accumulator safe? Yes, but scary.
1067 Variable* variable = expr->target()->AsVariableProxy()->var(); 1047 Variable* variable = expr->target()->AsVariableProxy()->var();
1068 VisitVariableAssignment(variable, slot); 1048 VisitVariableAssignment(variable, slot);
1069 break; 1049 break;
1070 } 1050 }
1071 case NAMED_PROPERTY: 1051 case NAMED_PROPERTY:
1072 builder()->StoreNamedProperty(object, key, feedback_index(slot), 1052 builder()->StoreNamedProperty(object, name_index, feedback_index(slot),
1073 language_mode()); 1053 language_mode());
1074 break; 1054 break;
1075 case KEYED_PROPERTY: 1055 case KEYED_PROPERTY:
1076 builder()->StoreKeyedProperty(object, key, feedback_index(slot), 1056 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
1077 language_mode()); 1057 language_mode());
1078 break; 1058 break;
1079 case NAMED_SUPER_PROPERTY: 1059 case NAMED_SUPER_PROPERTY:
1080 case KEYED_SUPER_PROPERTY: 1060 case KEYED_SUPER_PROPERTY:
1081 UNIMPLEMENTED(); 1061 UNIMPLEMENTED();
1082 } 1062 }
(...skipping 10 matching lines...) Expand all
1093 } 1073 }
1094 1074
1095 1075
1096 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { 1076 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
1097 LhsKind property_kind = Property::GetAssignType(expr); 1077 LhsKind property_kind = Property::GetAssignType(expr);
1098 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot(); 1078 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot();
1099 switch (property_kind) { 1079 switch (property_kind) {
1100 case VARIABLE: 1080 case VARIABLE:
1101 UNREACHABLE(); 1081 UNREACHABLE();
1102 case NAMED_PROPERTY: { 1082 case NAMED_PROPERTY: {
1103 builder()->LoadLiteral(expr->key()->AsLiteral()->AsPropertyName()); 1083 size_t name_index = builder()->GetConstantPoolEntry(
1104 builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode()); 1084 expr->key()->AsLiteral()->AsPropertyName());
1085 builder()->LoadNamedProperty(obj, name_index, feedback_index(slot),
1086 language_mode());
1105 break; 1087 break;
1106 } 1088 }
1107 case KEYED_PROPERTY: { 1089 case KEYED_PROPERTY: {
1108 VisitForAccumulatorValue(expr->key()); 1090 VisitForAccumulatorValue(expr->key());
1109 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); 1091 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode());
1110 break; 1092 break;
1111 } 1093 }
1112 case NAMED_SUPER_PROPERTY: 1094 case NAMED_SUPER_PROPERTY:
1113 case KEYED_SUPER_PROPERTY: 1095 case KEYED_SUPER_PROPERTY:
1114 UNIMPLEMENTED(); 1096 UNIMPLEMENTED();
1115 } 1097 }
1116 execution_result()->SetResultInAccumulator();
oth 2015/10/22 10:54:30 I find this function scary. It is setting the resu
rmcilroy 2015/10/22 13:27:48 Done - added VisitPropertyLoadForAccumulator for t
1117 } 1098 }
1118 1099
1119 1100
1120 void BytecodeGenerator::VisitProperty(Property* expr) { 1101 void BytecodeGenerator::VisitProperty(Property* expr) {
1121 Register obj = VisitForRegisterValue(expr->obj()); 1102 Register obj = VisitForRegisterValue(expr->obj());
1122 VisitPropertyLoad(obj, expr); 1103 VisitPropertyLoad(obj, expr);
1104 execution_result()->SetResultInAccumulator();
1123 } 1105 }
1124 1106
1125 1107
1126 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { 1108 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) {
1127 // Visit arguments and place in a contiguous block of temporary 1109 // Visit arguments and place in a contiguous block of temporary
1128 // registers. Return the first temporary register corresponding to 1110 // registers. Return the first temporary register corresponding to
1129 // the first argument. 1111 // the first argument.
1130 // 1112 //
1131 // NB the caller may have already called 1113 // NB the caller may have already called
1132 // PrepareForConsecutiveAllocations() with args->length() + N. The 1114 // PrepareForConsecutiveAllocations() with args->length() + N. The
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 ZoneList<Expression*>* args = expr->arguments(); 1148 ZoneList<Expression*>* args = expr->arguments();
1167 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1); 1149 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1);
1168 Register receiver = execution_result()->NextConsecutiveRegister(); 1150 Register receiver = execution_result()->NextConsecutiveRegister();
1169 1151
1170 switch (call_type) { 1152 switch (call_type) {
1171 case Call::PROPERTY_CALL: { 1153 case Call::PROPERTY_CALL: {
1172 Property* property = callee_expr->AsProperty(); 1154 Property* property = callee_expr->AsProperty();
1173 if (property->IsSuperAccess()) { 1155 if (property->IsSuperAccess()) {
1174 UNIMPLEMENTED(); 1156 UNIMPLEMENTED();
1175 } 1157 }
1158
1176 VisitForAccumulatorValue(property->obj()); 1159 VisitForAccumulatorValue(property->obj());
1177 builder()->StoreAccumulatorInRegister(receiver); 1160 builder()->StoreAccumulatorInRegister(receiver);
1178 // Need a result scope here to keep our consecutive
1179 // temporaries.
1180 AccumulatorResultScope accumulator_execution_result(this);
1181 // Perform a property load of the callee.
1182 VisitPropertyLoad(receiver, property); 1161 VisitPropertyLoad(receiver, property);
1183 builder()->StoreAccumulatorInRegister(callee); 1162 builder()->StoreAccumulatorInRegister(callee);
1184 break; 1163 break;
1185 } 1164 }
1186 case Call::GLOBAL_CALL: { 1165 case Call::GLOBAL_CALL: {
1187 // Receiver is undefined for global calls. 1166 // Receiver is undefined for global calls.
1188 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 1167 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
1189 // Load callee as a global variable. 1168 // Load callee as a global variable.
1190 VariableProxy* proxy = callee_expr->AsVariableProxy(); 1169 VariableProxy* proxy = callee_expr->AsVariableProxy();
1191 // Result scope for VisitVariableLoad to avoid using our temporaries 1170 // Result scope for VisitVariableLoad to avoid using our temporaries
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 } 1488 }
1510 } 1489 }
1511 1490
1512 1491
1513 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, 1492 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
1514 ObjectLiteralProperty* property, 1493 ObjectLiteralProperty* property,
1515 int slot_number) { 1494 int slot_number) {
1516 Expression* expr = property->value(); 1495 Expression* expr = property->value();
1517 if (!FunctionLiteral::NeedsHomeObject(expr)) return; 1496 if (!FunctionLiteral::NeedsHomeObject(expr)) return;
1518 1497
1519 // TODO(rmcilroy): Remove UNIMPLEMENTED once we have tests for setting the
1520 // home object.
1521 UNIMPLEMENTED(); 1498 UNIMPLEMENTED();
1522
1523 TemporaryRegisterScope temporary_register_scope(builder());
1524 Register name = temporary_register_scope.NewRegister();
1525 isolate()->factory()->home_object_symbol();
1526 builder()
1527 ->LoadLiteral(isolate()->factory()->home_object_symbol())
1528 .StoreAccumulatorInRegister(name)
1529 .StoreNamedProperty(home_object, name,
1530 feedback_index(property->GetSlot(slot_number)),
1531 language_mode());
1532 } 1499 }
1533 1500
1534 1501
1535 void BytecodeGenerator::VisitFunctionClosureForContext() { 1502 void BytecodeGenerator::VisitFunctionClosureForContext() {
1536 Scope* closure_scope = execution_context()->scope()->ClosureScope(); 1503 Scope* closure_scope = execution_context()->scope()->ClosureScope();
1537 if (closure_scope->is_script_scope() || 1504 if (closure_scope->is_script_scope() ||
1538 closure_scope->is_module_scope()) { 1505 closure_scope->is_module_scope()) {
1539 // Contexts nested in the native context have a canonical empty function as 1506 // Contexts nested in the native context have a canonical empty function as
1540 // their closure, not the anonymous closure containing the global code. 1507 // their closure, not the anonymous closure containing the global code.
1541 // Pass a SMI sentinel and let the runtime look up the empty function. 1508 // Pass a SMI sentinel and let the runtime look up the empty function.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 } 1601 }
1635 1602
1636 1603
1637 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 1604 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
1638 return info()->feedback_vector()->GetIndex(slot); 1605 return info()->feedback_vector()->GetIndex(slot);
1639 } 1606 }
1640 1607
1641 } // namespace interpreter 1608 } // namespace interpreter
1642 } // namespace internal 1609 } // namespace internal
1643 } // namespace v8 1610 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698