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

Side by Side Diff: src/ia32/lithium-ia32.cc

Issue 93803003: Fixed Lithium environment generation bug for captured objects (created (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/x64/lithium-x64.h » ('j') | 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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 new(zone()) LEnvironment(hydrogen_env->closure(), 1017 new(zone()) LEnvironment(hydrogen_env->closure(),
1018 hydrogen_env->frame_type(), 1018 hydrogen_env->frame_type(),
1019 ast_id, 1019 ast_id,
1020 hydrogen_env->parameter_count(), 1020 hydrogen_env->parameter_count(),
1021 argument_count_, 1021 argument_count_,
1022 value_count, 1022 value_count,
1023 outer, 1023 outer,
1024 hydrogen_env->entry(), 1024 hydrogen_env->entry(),
1025 zone()); 1025 zone());
1026 int argument_index = *argument_index_accumulator; 1026 int argument_index = *argument_index_accumulator;
1027 int object_index = objects_to_materialize->length(); 1027
1028 // Store the environment description into the environment
1029 // (with holes for nested objects)
1028 for (int i = 0; i < hydrogen_env->length(); ++i) { 1030 for (int i = 0; i < hydrogen_env->length(); ++i) {
1029 if (hydrogen_env->is_special_index(i)) continue; 1031 if (hydrogen_env->is_special_index(i)) continue;
1030 1032
1031 LOperand* op; 1033 LOperand* op;
1032 HValue* value = hydrogen_env->values()->at(i); 1034 HValue* value = hydrogen_env->values()->at(i);
1033 if (value->IsArgumentsObject() || value->IsCapturedObject()) { 1035 if (value->IsArgumentsObject() || value->IsCapturedObject()) {
1034 objects_to_materialize->Add(value, zone());
1035 op = LEnvironment::materialization_marker(); 1036 op = LEnvironment::materialization_marker();
1036 } else if (value->IsPushArgument()) { 1037 } else if (value->IsPushArgument()) {
1037 op = new(zone()) LArgument(argument_index++); 1038 op = new(zone()) LArgument(argument_index++);
1038 } else { 1039 } else {
1039 op = UseAny(value); 1040 op = UseAny(value);
1040 } 1041 }
1041 result->AddValue(op, 1042 result->AddValue(op,
1042 value->representation(), 1043 value->representation(),
1043 value->CheckFlag(HInstruction::kUint32)); 1044 value->CheckFlag(HInstruction::kUint32));
1044 } 1045 }
1045 1046
1046 for (int i = object_index; i < objects_to_materialize->length(); ++i) { 1047 // Recursively store the nested objects into the environment
1047 HValue* object_to_materialize = objects_to_materialize->at(i); 1048 for (int i = 0; i < hydrogen_env->length(); ++i) {
1048 int previously_materialized_object = -1; 1049 if (hydrogen_env->is_special_index(i)) continue;
1049 for (int prev = 0; prev < i; ++prev) { 1050
1050 if (objects_to_materialize->at(prev) == objects_to_materialize->at(i)) { 1051 HValue* value = hydrogen_env->values()->at(i);
1051 previously_materialized_object = prev; 1052 if (value->IsArgumentsObject() || value->IsCapturedObject()) {
1052 break; 1053 AddObjectToMaterialize(value, objects_to_materialize, result);
1053 }
1054 }
1055 int length = object_to_materialize->OperandCount();
1056 bool is_arguments = object_to_materialize->IsArgumentsObject();
1057 if (previously_materialized_object >= 0) {
1058 result->AddDuplicateObject(previously_materialized_object);
1059 continue;
1060 } else {
1061 result->AddNewObject(is_arguments ? length - 1 : length, is_arguments);
1062 }
1063 for (int i = is_arguments ? 1 : 0; i < length; ++i) {
1064 LOperand* op;
1065 HValue* value = object_to_materialize->OperandAt(i);
1066 if (value->IsArgumentsObject() || value->IsCapturedObject()) {
1067 objects_to_materialize->Add(value, zone());
1068 op = LEnvironment::materialization_marker();
1069 } else {
1070 ASSERT(!value->IsPushArgument());
1071 op = UseAny(value);
1072 }
1073 result->AddValue(op,
1074 value->representation(),
1075 value->CheckFlag(HInstruction::kUint32));
1076 } 1054 }
1077 } 1055 }
1078 1056
1079 if (hydrogen_env->frame_type() == JS_FUNCTION) { 1057 if (hydrogen_env->frame_type() == JS_FUNCTION) {
1080 *argument_index_accumulator = argument_index; 1058 *argument_index_accumulator = argument_index;
1081 } 1059 }
1082 1060
1083 return result; 1061 return result;
1084 } 1062 }
1085 1063
1086 1064
1065 // Add an object to the supplied environment and object materialization list.
1066 //
1067 // Notes:
1068 //
1069 // We are building three lists here:
1070 //
1071 // 1. In the result->object_mapping_ list (added to by the
1072 // LEnvironment::Add*Object methods), we store the lengths (number
1073 // of fields) of the captured objects in depth-first traversal order, or
1074 // in case of duplicated objects, we store the index to the duplicate object
1075 // (with a tag to differentiate between captured and duplicated objects).
1076 //
1077 // 2. The object fields are stored in the result->values_ list
1078 // (added to by the LEnvironment.AddValue method) sequentially as lists
1079 // of fields with holes for nested objects (the holes will be expanded
1080 // later by LCodegen::AddToTranslation according to the
1081 // LEnvironment.object_mapping_ list).
1082 //
1083 // 3. The auxiliary objects_to_materialize array stores the hydrogen values
1084 // in the same order as result->object_mapping_ list. This is used
1085 // to detect duplicate values and calculate the corresponding object index.
1086 void LChunkBuilder::AddObjectToMaterialize(HValue* value,
1087 ZoneList<HValue*>* objects_to_materialize, LEnvironment* result) {
titzer 2013/12/20 13:38:57 AFAICT, this method is an exact duplicate on all t
1088 int object_index = objects_to_materialize->length();
1089 // Store the hydrogen value into the de-duplication array
1090 objects_to_materialize->Add(value, zone());
1091 // Find out whether we are storing a duplicated value
1092 int previously_materialized_object = -1;
1093 for (int prev = 0; prev < object_index; ++prev) {
1094 if (objects_to_materialize->at(prev) == value) {
1095 previously_materialized_object = prev;
1096 break;
1097 }
1098 }
1099 // Store the captured object length (or duplicated object index)
1100 // into the environment. For duplicated objects, we stop here.
1101 int length = value->OperandCount();
1102 bool is_arguments = value->IsArgumentsObject();
1103 if (previously_materialized_object >= 0) {
1104 result->AddDuplicateObject(previously_materialized_object);
1105 return;
1106 } else {
1107 result->AddNewObject(is_arguments ? length - 1 : length, is_arguments);
1108 }
1109 // Store the captured object's fields into the environment
1110 for (int i = is_arguments ? 1 : 0; i < length; ++i) {
1111 LOperand* op;
1112 HValue* arg_value = value->OperandAt(i);
1113 if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
1114 // Insert a hole for nested objects
1115 op = LEnvironment::materialization_marker();
1116 } else {
1117 ASSERT(!arg_value->IsPushArgument());
1118 // For ordinary values, tell the register allocator we need the value
1119 // to be alive here
1120 op = UseAny(arg_value);
1121 }
1122 result->AddValue(op,
1123 arg_value->representation(),
1124 arg_value->CheckFlag(HInstruction::kUint32));
1125 }
1126 // Recursively store all the nested captured objects into the environment
1127 for (int i = is_arguments ? 1 : 0; i < length; ++i) {
1128 HValue* arg_value = value->OperandAt(i);
1129 if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
1130 AddObjectToMaterialize(arg_value, objects_to_materialize, result);
1131 }
1132 }
1133 }
1134
1135
1087 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 1136 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1088 return new(zone()) LGoto(instr->FirstSuccessor()); 1137 return new(zone()) LGoto(instr->FirstSuccessor());
1089 } 1138 }
1090 1139
1091 1140
1092 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { 1141 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
1093 LInstruction* goto_instr = CheckElideControlInstruction(instr); 1142 LInstruction* goto_instr = CheckElideControlInstruction(instr);
1094 if (goto_instr != NULL) return goto_instr; 1143 if (goto_instr != NULL) return goto_instr;
1095 1144
1096 ToBooleanStub::Types expected = instr->expected_input_types(); 1145 ToBooleanStub::Types expected = instr->expected_input_types();
(...skipping 1667 matching lines...) Expand 10 before | Expand all | Expand 10 after
2764 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2813 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2765 LOperand* object = UseRegister(instr->object()); 2814 LOperand* object = UseRegister(instr->object());
2766 LOperand* index = UseTempRegister(instr->index()); 2815 LOperand* index = UseTempRegister(instr->index());
2767 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); 2816 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
2768 } 2817 }
2769 2818
2770 2819
2771 } } // namespace v8::internal 2820 } } // namespace v8::internal
2772 2821
2773 #endif // V8_TARGET_ARCH_IA32 2822 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698