Chromium Code Reviews| 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.ObjectPool()), | 31 object_pool_(code.ObjectPool()), |
| 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 timeline_event_ = compiler_stream->RecordEvent(); | |
| 103 if (timeline_event_ != NULL) { | |
| 104 timeline_event_->DurationBegin(compiler_stream, "Deoptimize"); | |
| 105 timeline_event_->SetNumArguments(3); | |
| 106 timeline_event_->CopyArgument( | |
| 107 0, | |
| 108 "function", | |
| 109 const_cast<char*>(function.QualifiedUserVisibleNameCString())); | |
|
rmacnak
2015/06/10 20:25:14
The whole leaf runtime entry is in a NoSafepointSc
Cutch
2015/06/10 21:20:57
Done.
| |
| 110 timeline_event_->CopyArgument( | |
| 111 1, | |
| 112 "reason", | |
| 113 const_cast<char*>(DeoptReasonToCString(deopt_reason()))); | |
| 114 timeline_event_->FormatArgument( | |
| 115 2, | |
| 116 "deoptimizationCount", | |
| 117 "%d", | |
| 118 function.deoptimization_counter()); | |
| 119 } | |
| 120 } | |
| 121 | |
| 95 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { | 122 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { |
| 96 OS::PrintErr( | 123 OS::PrintErr( |
| 97 "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n", | 124 "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n", |
| 98 deopt_reason(), | 125 deopt_reason(), |
| 99 DeoptReasonToCString(deopt_reason()), | 126 DeoptReasonToCString(deopt_reason()), |
| 100 frame->pc(), | 127 frame->pc(), |
| 101 function.ToFullyQualifiedCString(), | 128 function.ToFullyQualifiedCString(), |
| 102 function.deoptimization_counter()); | 129 function.deoptimization_counter()); |
| 103 } | 130 } |
| 104 } | 131 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 119 } | 146 } |
| 120 dest_frame_ = NULL; | 147 dest_frame_ = NULL; |
| 121 | 148 |
| 122 // Delete all deferred objects. | 149 // Delete all deferred objects. |
| 123 for (intptr_t i = 0; i < deferred_objects_count_; i++) { | 150 for (intptr_t i = 0; i < deferred_objects_count_; i++) { |
| 124 delete deferred_objects_[i]; | 151 delete deferred_objects_[i]; |
| 125 } | 152 } |
| 126 delete[] deferred_objects_; | 153 delete[] deferred_objects_; |
| 127 deferred_objects_ = NULL; | 154 deferred_objects_ = NULL; |
| 128 deferred_objects_count_ = 0; | 155 deferred_objects_count_ = 0; |
| 156 if (timeline_event_ != NULL) { | |
| 157 timeline_event_->DurationEnd(); | |
| 158 } | |
| 129 } | 159 } |
| 130 | 160 |
| 131 | 161 |
| 132 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 162 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 133 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); | 163 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); |
| 134 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); | 164 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); |
| 135 | 165 |
| 136 // Visit any object pointers on the destination stack. | 166 // Visit any object pointers on the destination stack. |
| 137 if (dest_frame_is_allocated_) { | 167 if (dest_frame_is_allocated_) { |
| 138 for (intptr_t i = 0; i < dest_frame_size_; i++) { | 168 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, | 1290 Smi* offset, |
| 1261 TypedData* info, | 1291 TypedData* info, |
| 1262 Smi* reason) { | 1292 Smi* reason) { |
| 1263 intptr_t i = index * kEntrySize; | 1293 intptr_t i = index * kEntrySize; |
| 1264 *offset ^= table.At(i); | 1294 *offset ^= table.At(i); |
| 1265 *info ^= table.At(i + 1); | 1295 *info ^= table.At(i + 1); |
| 1266 *reason ^= table.At(i + 2); | 1296 *reason ^= table.At(i + 2); |
| 1267 } | 1297 } |
| 1268 | 1298 |
| 1269 } // namespace dart | 1299 } // namespace dart |
| OLD | NEW |