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