| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/deopt_instructions.h" | 5 #include "vm/deopt_instructions.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/intermediate_language.h" | 10 #include "vm/intermediate_language.h" |
| 11 #include "vm/locations.h" | 11 #include "vm/locations.h" |
| 12 #include "vm/parser.h" | 12 #include "vm/parser.h" |
| 13 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" |
| 14 #include "vm/thread.h" | 14 #include "vm/thread.h" |
| 15 #include "vm/timeline.h" |
| 15 | 16 |
| 16 namespace dart { | 17 namespace dart { |
| 17 | 18 |
| 18 DEFINE_FLAG(bool, compress_deopt_info, true, | 19 DEFINE_FLAG(bool, compress_deopt_info, true, |
| 19 "Compress the size of the deoptimization info for optimized code."); | 20 "Compress the size of the deoptimization info for optimized code."); |
| 20 DECLARE_FLAG(bool, trace_deoptimization); | 21 DECLARE_FLAG(bool, trace_deoptimization); |
| 21 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 22 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
| 22 | 23 |
| 23 | 24 |
| 24 DeoptContext::DeoptContext(const StackFrame* frame, | 25 DeoptContext::DeoptContext(const StackFrame* frame, |
| 25 const Code& code, | 26 const Code& code, |
| 26 DestFrameOptions dest_options, | 27 DestFrameOptions dest_options, |
| 27 fpu_register_t* fpu_registers, | 28 fpu_register_t* fpu_registers, |
| 28 intptr_t* cpu_registers) | 29 intptr_t* cpu_registers) |
| 29 : code_(code.raw()), | 30 : code_(code.raw()), |
| 30 object_pool_(code.GetObjectPool()), | 31 object_pool_(code.GetObjectPool()), |
| 31 deopt_info_(TypedData::null()), | 32 deopt_info_(TypedData::null()), |
| 32 dest_frame_is_allocated_(false), | 33 dest_frame_is_allocated_(false), |
| 33 dest_frame_(NULL), | 34 dest_frame_(NULL), |
| 34 dest_frame_size_(0), | 35 dest_frame_size_(0), |
| 35 source_frame_is_allocated_(false), | 36 source_frame_is_allocated_(false), |
| 36 source_frame_(NULL), | 37 source_frame_(NULL), |
| 37 source_frame_size_(0), | 38 source_frame_size_(0), |
| 38 cpu_registers_(cpu_registers), | 39 cpu_registers_(cpu_registers), |
| 39 fpu_registers_(fpu_registers), | 40 fpu_registers_(fpu_registers), |
| 40 num_args_(0), | 41 num_args_(0), |
| 41 deopt_reason_(ICData::kDeoptUnknown), | 42 deopt_reason_(ICData::kDeoptUnknown), |
| 42 deopt_flags_(0), | 43 deopt_flags_(0), |
| 43 thread_(Thread::Current()), | 44 thread_(Thread::Current()), |
| 45 timeline_event_(NULL), |
| 44 deferred_slots_(NULL), | 46 deferred_slots_(NULL), |
| 45 deferred_objects_count_(0), | 47 deferred_objects_count_(0), |
| 46 deferred_objects_(NULL) { | 48 deferred_objects_(NULL) { |
| 47 const TypedData& deopt_info = TypedData::Handle( | 49 const TypedData& deopt_info = TypedData::Handle( |
| 48 code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_)); | 50 code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_)); |
| 49 ASSERT(!deopt_info.IsNull()); | 51 ASSERT(!deopt_info.IsNull()); |
| 50 deopt_info_ = deopt_info.raw(); | 52 deopt_info_ = deopt_info.raw(); |
| 51 | 53 |
| 52 const Function& function = Function::Handle(code.function()); | 54 const Function& function = Function::Handle(code.function()); |
| 53 | 55 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 | 87 |
| 86 if (dest_options == kDestIsAllocated) { | 88 if (dest_options == kDestIsAllocated) { |
| 87 dest_frame_ = new intptr_t[dest_frame_size_]; | 89 dest_frame_ = new intptr_t[dest_frame_size_]; |
| 88 ASSERT(source_frame_ != NULL); | 90 ASSERT(source_frame_ != NULL); |
| 89 for (intptr_t i = 0; i < dest_frame_size_; i++) { | 91 for (intptr_t i = 0; i < dest_frame_size_; i++) { |
| 90 dest_frame_[i] = 0; | 92 dest_frame_[i] = 0; |
| 91 } | 93 } |
| 92 dest_frame_is_allocated_ = true; | 94 dest_frame_is_allocated_ = true; |
| 93 } | 95 } |
| 94 | 96 |
| 97 if (dest_options != kDestIsAllocated) { |
| 98 // kDestIsAllocated is used by the debugger to generate a stack trace |
| 99 // and does not signal a real deopt. |
| 100 Isolate* isolate = Isolate::Current(); |
| 101 TimelineStream* compiler_stream = isolate->GetCompilerStream(); |
| 102 ASSERT(compiler_stream != NULL); |
| 103 timeline_event_ = compiler_stream->RecordEvent(); |
| 104 if (timeline_event_ != NULL) { |
| 105 timeline_event_->DurationBegin(compiler_stream, "Deoptimize"); |
| 106 timeline_event_->SetNumArguments(3); |
| 107 } |
| 108 } |
| 109 |
| 95 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { | 110 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { |
| 96 OS::PrintErr( | 111 OS::PrintErr( |
| 97 "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n", | 112 "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n", |
| 98 deopt_reason(), | 113 deopt_reason(), |
| 99 DeoptReasonToCString(deopt_reason()), | 114 DeoptReasonToCString(deopt_reason()), |
| 100 frame->pc(), | 115 frame->pc(), |
| 101 function.ToFullyQualifiedCString(), | 116 function.ToFullyQualifiedCString(), |
| 102 function.deoptimization_counter()); | 117 function.deoptimization_counter()); |
| 103 } | 118 } |
| 104 } | 119 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 119 } | 134 } |
| 120 dest_frame_ = NULL; | 135 dest_frame_ = NULL; |
| 121 | 136 |
| 122 // Delete all deferred objects. | 137 // Delete all deferred objects. |
| 123 for (intptr_t i = 0; i < deferred_objects_count_; i++) { | 138 for (intptr_t i = 0; i < deferred_objects_count_; i++) { |
| 124 delete deferred_objects_[i]; | 139 delete deferred_objects_[i]; |
| 125 } | 140 } |
| 126 delete[] deferred_objects_; | 141 delete[] deferred_objects_; |
| 127 deferred_objects_ = NULL; | 142 deferred_objects_ = NULL; |
| 128 deferred_objects_count_ = 0; | 143 deferred_objects_count_ = 0; |
| 144 if (timeline_event_ != NULL) { |
| 145 const Code& code = Code::Handle(zone(), code_); |
| 146 const Function& function = Function::Handle(zone(), code.function()); |
| 147 timeline_event_->CopyArgument( |
| 148 0, |
| 149 "function", |
| 150 const_cast<char*>(function.QualifiedUserVisibleNameCString())); |
| 151 timeline_event_->CopyArgument( |
| 152 1, |
| 153 "reason", |
| 154 const_cast<char*>(DeoptReasonToCString(deopt_reason()))); |
| 155 timeline_event_->FormatArgument( |
| 156 2, |
| 157 "deoptimizationCount", |
| 158 "%d", |
| 159 function.deoptimization_counter()); |
| 160 timeline_event_->DurationEnd(); |
| 161 } |
| 129 } | 162 } |
| 130 | 163 |
| 131 | 164 |
| 132 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 165 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 133 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); | 166 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); |
| 134 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); | 167 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); |
| 135 | 168 |
| 136 // Visit any object pointers on the destination stack. | 169 // Visit any object pointers on the destination stack. |
| 137 if (dest_frame_is_allocated_) { | 170 if (dest_frame_is_allocated_) { |
| 138 for (intptr_t i = 0; i < dest_frame_size_; i++) { | 171 for (intptr_t i = 0; i < dest_frame_size_; i++) { |
| (...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 Smi* offset, | 1293 Smi* offset, |
| 1261 TypedData* info, | 1294 TypedData* info, |
| 1262 Smi* reason) { | 1295 Smi* reason) { |
| 1263 intptr_t i = index * kEntrySize; | 1296 intptr_t i = index * kEntrySize; |
| 1264 *offset ^= table.At(i); | 1297 *offset ^= table.At(i); |
| 1265 *info ^= table.At(i + 1); | 1298 *info ^= table.At(i + 1); |
| 1266 *reason ^= table.At(i + 2); | 1299 *reason ^= table.At(i + 2); |
| 1267 } | 1300 } |
| 1268 | 1301 |
| 1269 } // namespace dart | 1302 } // namespace dart |
| OLD | NEW |