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

Side by Side Diff: src/x64/lithium-x64.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
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 942 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 hydrogen_env->closure(), 953 hydrogen_env->closure(),
954 hydrogen_env->frame_type(), 954 hydrogen_env->frame_type(),
955 ast_id, 955 ast_id,
956 hydrogen_env->parameter_count(), 956 hydrogen_env->parameter_count(),
957 argument_count_, 957 argument_count_,
958 value_count, 958 value_count,
959 outer, 959 outer,
960 hydrogen_env->entry(), 960 hydrogen_env->entry(),
961 zone()); 961 zone());
962 int argument_index = *argument_index_accumulator; 962 int argument_index = *argument_index_accumulator;
963 int object_index = objects_to_materialize->length(); 963
964 // Store the environment description into the environment
965 // (with holes for nested objects)
964 for (int i = 0; i < hydrogen_env->length(); ++i) { 966 for (int i = 0; i < hydrogen_env->length(); ++i) {
965 if (hydrogen_env->is_special_index(i)) continue; 967 if (hydrogen_env->is_special_index(i)) continue;
966 968
967 LOperand* op; 969 LOperand* op;
968 HValue* value = hydrogen_env->values()->at(i); 970 HValue* value = hydrogen_env->values()->at(i);
969 if (value->IsArgumentsObject() || value->IsCapturedObject()) { 971 if (value->IsArgumentsObject() || value->IsCapturedObject()) {
970 objects_to_materialize->Add(value, zone());
971 op = LEnvironment::materialization_marker(); 972 op = LEnvironment::materialization_marker();
972 } else if (value->IsPushArgument()) { 973 } else if (value->IsPushArgument()) {
973 op = new(zone()) LArgument(argument_index++); 974 op = new(zone()) LArgument(argument_index++);
974 } else { 975 } else {
975 op = UseAny(value); 976 op = UseAny(value);
976 } 977 }
977 result->AddValue(op, 978 result->AddValue(op,
978 value->representation(), 979 value->representation(),
979 value->CheckFlag(HInstruction::kUint32)); 980 value->CheckFlag(HInstruction::kUint32));
980 } 981 }
981 982
982 for (int i = object_index; i < objects_to_materialize->length(); ++i) { 983 // Recursively store the nested objects into the environment
983 HValue* object_to_materialize = objects_to_materialize->at(i); 984 for (int i = 0; i < hydrogen_env->length(); ++i) {
984 int previously_materialized_object = -1; 985 if (hydrogen_env->is_special_index(i)) continue;
985 for (int prev = 0; prev < i; ++prev) { 986
986 if (objects_to_materialize->at(prev) == objects_to_materialize->at(i)) { 987 HValue* value = hydrogen_env->values()->at(i);
987 previously_materialized_object = prev; 988 if (value->IsArgumentsObject() || value->IsCapturedObject()) {
988 break; 989 AddObjectToMaterialize(value, objects_to_materialize, result);
989 }
990 }
991 int length = object_to_materialize->OperandCount();
992 bool is_arguments = object_to_materialize->IsArgumentsObject();
993 if (previously_materialized_object >= 0) {
994 result->AddDuplicateObject(previously_materialized_object);
995 continue;
996 } else {
997 result->AddNewObject(is_arguments ? length - 1 : length, is_arguments);
998 }
999 for (int i = is_arguments ? 1 : 0; i < length; ++i) {
1000 LOperand* op;
1001 HValue* value = object_to_materialize->OperandAt(i);
1002 if (value->IsArgumentsObject() || value->IsCapturedObject()) {
1003 objects_to_materialize->Add(value, zone());
1004 op = LEnvironment::materialization_marker();
1005 } else {
1006 ASSERT(!value->IsPushArgument());
1007 op = UseAny(value);
1008 }
1009 result->AddValue(op,
1010 value->representation(),
1011 value->CheckFlag(HInstruction::kUint32));
1012 } 990 }
1013 } 991 }
1014 992
1015 if (hydrogen_env->frame_type() == JS_FUNCTION) { 993 if (hydrogen_env->frame_type() == JS_FUNCTION) {
1016 *argument_index_accumulator = argument_index; 994 *argument_index_accumulator = argument_index;
1017 } 995 }
1018 996
1019 return result; 997 return result;
1020 } 998 }
1021 999
1022 1000
1001 // Add an object to the supplied environment and object materialization list.
1002 //
1003 // Notes:
1004 //
1005 // We are building three lists here:
1006 //
1007 // 1. In the result->object_mapping_ list (added to by the
1008 // LEnvironment::Add*Object methods), we store the lengths (number
1009 // of fields) of the captured objects in depth-first traversal order, or
1010 // in case of duplicated objects, we store the index to the duplicate object
1011 // (with a tag to differentiate between captured and duplicated objects).
1012 //
1013 // 2. The object fields are stored in the result->values_ list
1014 // (added to by the LEnvironment.AddValue method) sequentially as lists
1015 // of fields with holes for nested objects (the holes will be expanded
1016 // later by LCodegen::AddToTranslation according to the
1017 // LEnvironment.object_mapping_ list).
1018 //
1019 // 3. The auxiliary objects_to_materialize array stores the hydrogen values
1020 // in the same order as result->object_mapping_ list. This is used
1021 // to detect duplicate values and calculate the corresponding object index.
1022 void LChunkBuilder::AddObjectToMaterialize(HValue* value,
1023 ZoneList<HValue*>* objects_to_materialize, LEnvironment* result) {
1024 int object_index = objects_to_materialize->length();
1025 // Store the hydrogen value into the de-duplication array
1026 objects_to_materialize->Add(value, zone());
1027 // Find out whether we are storing a duplicated value
1028 int previously_materialized_object = -1;
1029 for (int prev = 0; prev < object_index; ++prev) {
1030 if (objects_to_materialize->at(prev) == value) {
1031 previously_materialized_object = prev;
1032 break;
1033 }
1034 }
1035 // Store the captured object length (or duplicated object index)
1036 // into the environment. For duplicated objects, we stop here.
1037 int length = value->OperandCount();
1038 bool is_arguments = value->IsArgumentsObject();
1039 if (previously_materialized_object >= 0) {
1040 result->AddDuplicateObject(previously_materialized_object);
1041 return;
1042 } else {
1043 result->AddNewObject(is_arguments ? length - 1 : length, is_arguments);
1044 }
1045 // Store the captured object's fields into the environment
1046 for (int i = is_arguments ? 1 : 0; i < length; ++i) {
1047 LOperand* op;
1048 HValue* arg_value = value->OperandAt(i);
1049 if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
1050 // Insert a hole for nested objects
1051 op = LEnvironment::materialization_marker();
1052 } else {
1053 ASSERT(!arg_value->IsPushArgument());
1054 // For ordinary values, tell the register allocator we need the value
1055 // to be alive here
1056 op = UseAny(arg_value);
1057 }
1058 result->AddValue(op,
1059 arg_value->representation(),
1060 arg_value->CheckFlag(HInstruction::kUint32));
1061 }
1062 // Recursively store all the nested captured objects into the environment
1063 for (int i = is_arguments ? 1 : 0; i < length; ++i) {
1064 HValue* arg_value = value->OperandAt(i);
1065 if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
1066 AddObjectToMaterialize(arg_value, objects_to_materialize, result);
1067 }
1068 }
1069 }
1070
1071
1023 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 1072 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1024 return new(zone()) LGoto(instr->FirstSuccessor()); 1073 return new(zone()) LGoto(instr->FirstSuccessor());
1025 } 1074 }
1026 1075
1027 1076
1028 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { 1077 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
1029 return new(zone()) LDebugBreak(); 1078 return new(zone()) LDebugBreak();
1030 } 1079 }
1031 1080
1032 1081
(...skipping 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2658 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2610 LOperand* object = UseRegister(instr->object()); 2659 LOperand* object = UseRegister(instr->object());
2611 LOperand* index = UseTempRegister(instr->index()); 2660 LOperand* index = UseTempRegister(instr->index());
2612 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); 2661 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
2613 } 2662 }
2614 2663
2615 2664
2616 } } // namespace v8::internal 2665 } } // namespace v8::internal
2617 2666
2618 #endif // V8_TARGET_ARCH_X64 2667 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698