OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/disasm.h" | 10 #include "src/disasm.h" |
(...skipping 3172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3183 } | 3183 } |
3184 | 3184 |
3185 FATAL("We should never get here - unexpected deopt info."); | 3185 FATAL("We should never get here - unexpected deopt info."); |
3186 return SlotRef(); | 3186 return SlotRef(); |
3187 } | 3187 } |
3188 | 3188 |
3189 | 3189 |
3190 SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, | 3190 SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, |
3191 int inlined_jsframe_index, | 3191 int inlined_jsframe_index, |
3192 int formal_parameter_count) | 3192 int formal_parameter_count) |
3193 : current_slot_(0), args_length_(-1), first_slot_index_(-1) { | 3193 : current_slot_(0), |
| 3194 args_length_(-1), |
| 3195 first_slot_index_(-1), |
| 3196 should_deoptimize_(false) { |
3194 DisallowHeapAllocation no_gc; | 3197 DisallowHeapAllocation no_gc; |
3195 | 3198 |
3196 int deopt_index = Safepoint::kNoDeoptimizationIndex; | 3199 int deopt_index = Safepoint::kNoDeoptimizationIndex; |
3197 DeoptimizationInputData* data = | 3200 DeoptimizationInputData* data = |
3198 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); | 3201 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); |
3199 TranslationIterator it(data->TranslationByteArray(), | 3202 TranslationIterator it(data->TranslationByteArray(), |
3200 data->TranslationIndex(deopt_index)->value()); | 3203 data->TranslationIndex(deopt_index)->value()); |
3201 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); | 3204 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
3202 CHECK_EQ(opcode, Translation::BEGIN); | 3205 CHECK_EQ(opcode, Translation::BEGIN); |
3203 it.Next(); // Drop frame count. | 3206 it.Next(); // Drop frame count. |
3204 | 3207 |
3205 stack_frame_id_ = frame->fp(); | 3208 stack_frame_id_ = frame->fp(); |
3206 | 3209 |
3207 int jsframe_count = it.Next(); | 3210 int jsframe_count = it.Next(); |
3208 CHECK_GT(jsframe_count, inlined_jsframe_index); | 3211 CHECK_GT(jsframe_count, inlined_jsframe_index); |
3209 int jsframes_to_skip = inlined_jsframe_index; | 3212 int jsframes_to_skip = inlined_jsframe_index; |
3210 int number_of_slots = -1; // Number of slots inside our frame (yet unknown) | 3213 int number_of_slots = -1; // Number of slots inside our frame (yet unknown) |
3211 bool should_deopt = false; | |
3212 while (number_of_slots != 0) { | 3214 while (number_of_slots != 0) { |
3213 opcode = static_cast<Translation::Opcode>(it.Next()); | 3215 opcode = static_cast<Translation::Opcode>(it.Next()); |
3214 bool processed = false; | 3216 bool processed = false; |
3215 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) { | 3217 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) { |
3216 if (jsframes_to_skip == 0) { | 3218 if (jsframes_to_skip == 0) { |
3217 CHECK_EQ(Translation::NumberOfOperandsFor(opcode), 2); | 3219 CHECK_EQ(Translation::NumberOfOperandsFor(opcode), 2); |
3218 | 3220 |
3219 it.Skip(1); // literal id | 3221 it.Skip(1); // literal id |
3220 int height = it.Next(); | 3222 int height = it.Next(); |
3221 | 3223 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3258 | 3260 |
3259 if (first_slot_index_ >= 0) { | 3261 if (first_slot_index_ >= 0) { |
3260 // We have found the beginning of our frame -> make sure we count | 3262 // We have found the beginning of our frame -> make sure we count |
3261 // the nested slots of captured objects | 3263 // the nested slots of captured objects |
3262 number_of_slots--; | 3264 number_of_slots--; |
3263 SlotRef& slot = slot_refs_.last(); | 3265 SlotRef& slot = slot_refs_.last(); |
3264 CHECK_NE(slot.Representation(), SlotRef::ARGUMENTS_OBJECT); | 3266 CHECK_NE(slot.Representation(), SlotRef::ARGUMENTS_OBJECT); |
3265 number_of_slots += slot.GetChildrenCount(); | 3267 number_of_slots += slot.GetChildrenCount(); |
3266 if (slot.Representation() == SlotRef::DEFERRED_OBJECT || | 3268 if (slot.Representation() == SlotRef::DEFERRED_OBJECT || |
3267 slot.Representation() == SlotRef::DUPLICATE_OBJECT) { | 3269 slot.Representation() == SlotRef::DUPLICATE_OBJECT) { |
3268 should_deopt = true; | 3270 should_deoptimize_ = true; |
3269 } | 3271 } |
3270 } | 3272 } |
3271 | 3273 |
3272 processed = true; | 3274 processed = true; |
3273 } | 3275 } |
3274 if (!processed) { | 3276 if (!processed) { |
3275 // Skip over operands to advance to the next opcode. | 3277 // Skip over operands to advance to the next opcode. |
3276 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 3278 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
3277 } | 3279 } |
3278 } | 3280 } |
3279 if (should_deopt) { | 3281 if (should_deoptimize_) { |
3280 List<JSFunction*> functions(2); | 3282 List<JSFunction*> functions(2); |
3281 frame->GetFunctions(&functions); | 3283 frame->GetFunctions(&functions); |
3282 Deoptimizer::DeoptimizeFunction(functions[0]); | 3284 Deoptimizer::DeoptimizeFunction(functions[0]); |
3283 } | 3285 } |
3284 } | 3286 } |
3285 | 3287 |
3286 | 3288 |
3287 Handle<Object> SlotRef::GetValue(Isolate* isolate) { | 3289 Handle<Object> SlotRef::GetValue(Isolate* isolate) { |
3288 switch (representation_) { | 3290 switch (representation_) { |
3289 case TAGGED: | 3291 case TAGGED: |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3485 | 3487 |
3486 FATAL("We should never get here - unexpected deopt slot kind."); | 3488 FATAL("We should never get here - unexpected deopt slot kind."); |
3487 return Handle<Object>::null(); | 3489 return Handle<Object>::null(); |
3488 } | 3490 } |
3489 | 3491 |
3490 | 3492 |
3491 void SlotRefValueBuilder::Finish(Isolate* isolate) { | 3493 void SlotRefValueBuilder::Finish(Isolate* isolate) { |
3492 // We should have processed all the slots | 3494 // We should have processed all the slots |
3493 CHECK_EQ(slot_refs_.length(), current_slot_); | 3495 CHECK_EQ(slot_refs_.length(), current_slot_); |
3494 | 3496 |
3495 if (materialized_objects_.length() > prev_materialized_count_) { | 3497 if (should_deoptimize_ && |
3496 // We have materialized some new objects, so we have to store them | 3498 materialized_objects_.length() > prev_materialized_count_) { |
3497 // to prevent duplicate materialization | 3499 // We have materialized some new objects and they might be accessible |
| 3500 // from the arguments object, so we have to store them |
| 3501 // to prevent duplicate materialization. |
3498 Handle<FixedArray> array = isolate->factory()->NewFixedArray( | 3502 Handle<FixedArray> array = isolate->factory()->NewFixedArray( |
3499 materialized_objects_.length()); | 3503 materialized_objects_.length()); |
3500 for (int i = 0; i < materialized_objects_.length(); i++) { | 3504 for (int i = 0; i < materialized_objects_.length(); i++) { |
3501 array->set(i, *(materialized_objects_.at(i))); | 3505 array->set(i, *(materialized_objects_.at(i))); |
3502 } | 3506 } |
3503 isolate->materialized_object_store()->Set(stack_frame_id_, array); | 3507 isolate->materialized_object_store()->Set(stack_frame_id_, array); |
3504 } | 3508 } |
3505 } | 3509 } |
3506 | 3510 |
3507 | 3511 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3663 Deoptimizer::GetDeoptimizationId(isolate, info->target_address(), | 3667 Deoptimizer::GetDeoptimizationId(isolate, info->target_address(), |
3664 Deoptimizer::LAZY))) { | 3668 Deoptimizer::LAZY))) { |
3665 CHECK(RelocInfo::IsRuntimeEntry(info->rmode())); | 3669 CHECK(RelocInfo::IsRuntimeEntry(info->rmode())); |
3666 return DeoptInfo(last_position, NULL, last_reason); | 3670 return DeoptInfo(last_position, NULL, last_reason); |
3667 } | 3671 } |
3668 } | 3672 } |
3669 } | 3673 } |
3670 return DeoptInfo(0, NULL, Deoptimizer::kNoReason); | 3674 return DeoptInfo(0, NULL, Deoptimizer::kNoReason); |
3671 } | 3675 } |
3672 } } // namespace v8::internal | 3676 } } // namespace v8::internal |
OLD | NEW |