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" |
(...skipping 25 matching lines...) Expand all Loading... |
36 dest_frame_size_(0), | 36 dest_frame_size_(0), |
37 source_frame_is_allocated_(false), | 37 source_frame_is_allocated_(false), |
38 source_frame_(NULL), | 38 source_frame_(NULL), |
39 source_frame_size_(0), | 39 source_frame_size_(0), |
40 cpu_registers_(cpu_registers), | 40 cpu_registers_(cpu_registers), |
41 fpu_registers_(fpu_registers), | 41 fpu_registers_(fpu_registers), |
42 num_args_(0), | 42 num_args_(0), |
43 deopt_reason_(ICData::kDeoptUnknown), | 43 deopt_reason_(ICData::kDeoptUnknown), |
44 deopt_flags_(0), | 44 deopt_flags_(0), |
45 thread_(Thread::Current()), | 45 thread_(Thread::Current()), |
46 timeline_event_(NULL), | 46 deopt_start_micros_(0), |
47 deferred_slots_(NULL), | 47 deferred_slots_(NULL), |
48 deferred_objects_count_(0), | 48 deferred_objects_count_(0), |
49 deferred_objects_(NULL), | 49 deferred_objects_(NULL), |
50 is_lazy_deopt_(is_lazy_deopt) { | 50 is_lazy_deopt_(is_lazy_deopt) { |
51 const TypedData& deopt_info = TypedData::Handle( | 51 const TypedData& deopt_info = TypedData::Handle( |
52 code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_)); | 52 code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_)); |
53 ASSERT(!deopt_info.IsNull()); | 53 ASSERT(!deopt_info.IsNull()); |
54 deopt_info_ = deopt_info.raw(); | 54 deopt_info_ = deopt_info.raw(); |
55 | 55 |
56 const Function& function = Function::Handle(code.function()); | 56 const Function& function = Function::Handle(code.function()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 ASSERT(source_frame_ != NULL); | 92 ASSERT(source_frame_ != NULL); |
93 for (intptr_t i = 0; i < dest_frame_size_; i++) { | 93 for (intptr_t i = 0; i < dest_frame_size_; i++) { |
94 dest_frame_[i] = 0; | 94 dest_frame_[i] = 0; |
95 } | 95 } |
96 dest_frame_is_allocated_ = true; | 96 dest_frame_is_allocated_ = true; |
97 } | 97 } |
98 | 98 |
99 if (dest_options != kDestIsAllocated) { | 99 if (dest_options != kDestIsAllocated) { |
100 // kDestIsAllocated is used by the debugger to generate a stack trace | 100 // kDestIsAllocated is used by the debugger to generate a stack trace |
101 // and does not signal a real deopt. | 101 // and does not signal a real deopt. |
102 Isolate* isolate = Isolate::Current(); | 102 deopt_start_micros_ = OS::GetCurrentMonotonicMicros(); |
103 TimelineStream* compiler_stream = isolate->GetCompilerStream(); | |
104 ASSERT(compiler_stream != NULL); | |
105 timeline_event_ = compiler_stream->StartEvent(); | |
106 if (timeline_event_ != NULL) { | |
107 timeline_event_->DurationBegin("Deoptimize"); | |
108 timeline_event_->SetNumArguments(3); | |
109 } | |
110 } | 103 } |
111 | 104 |
112 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { | 105 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { |
113 OS::PrintErr( | 106 OS::PrintErr( |
114 "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n", | 107 "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n", |
115 deopt_reason(), | 108 deopt_reason(), |
116 DeoptReasonToCString(deopt_reason()), | 109 DeoptReasonToCString(deopt_reason()), |
117 frame->pc(), | 110 frame->pc(), |
118 function.ToFullyQualifiedCString(), | 111 function.ToFullyQualifiedCString(), |
119 function.deoptimization_counter()); | 112 function.deoptimization_counter()); |
(...skipping 16 matching lines...) Expand all Loading... |
136 } | 129 } |
137 dest_frame_ = NULL; | 130 dest_frame_ = NULL; |
138 | 131 |
139 // Delete all deferred objects. | 132 // Delete all deferred objects. |
140 for (intptr_t i = 0; i < deferred_objects_count_; i++) { | 133 for (intptr_t i = 0; i < deferred_objects_count_; i++) { |
141 delete deferred_objects_[i]; | 134 delete deferred_objects_[i]; |
142 } | 135 } |
143 delete[] deferred_objects_; | 136 delete[] deferred_objects_; |
144 deferred_objects_ = NULL; | 137 deferred_objects_ = NULL; |
145 deferred_objects_count_ = 0; | 138 deferred_objects_count_ = 0; |
146 if (timeline_event_ != NULL) { | 139 if (deopt_start_micros_ != 0) { |
147 const Code& code = Code::Handle(zone(), code_); | 140 Isolate* isolate = Isolate::Current(); |
148 const Function& function = Function::Handle(zone(), code.function()); | 141 TimelineStream* compiler_stream = isolate->GetCompilerStream(); |
149 timeline_event_->CopyArgument( | 142 ASSERT(compiler_stream != NULL); |
150 0, | 143 if (compiler_stream->Enabled()) { |
151 "function", | 144 const Code& code = Code::Handle(zone(), code_); |
152 const_cast<char*>(function.QualifiedUserVisibleNameCString())); | 145 const Function& function = Function::Handle(zone(), code.function()); |
153 timeline_event_->CopyArgument( | 146 const char* function_name = function.QualifiedUserVisibleNameCString(); |
154 1, | 147 const char* reason = DeoptReasonToCString(deopt_reason()); |
155 "reason", | 148 int counter = function.deoptimization_counter(); |
156 const_cast<char*>(DeoptReasonToCString(deopt_reason()))); | 149 TimelineEvent* timeline_event = compiler_stream->StartEvent(); |
157 timeline_event_->FormatArgument( | 150 if (timeline_event != NULL) { |
158 2, | 151 timeline_event->Duration("Deoptimize", |
159 "deoptimizationCount", | 152 deopt_start_micros_, |
160 "%d", | 153 OS::GetCurrentMonotonicMicros()); |
161 function.deoptimization_counter()); | 154 timeline_event->SetNumArguments(3); |
162 timeline_event_->DurationEnd(); | 155 timeline_event->CopyArgument(0, "function", function_name); |
163 timeline_event_->Complete(); | 156 timeline_event->CopyArgument(1, "reason", reason); |
| 157 timeline_event->FormatArgument(2, "deoptimizationCount", "%d", counter); |
| 158 timeline_event->Complete(); |
| 159 } |
| 160 } |
164 } | 161 } |
165 } | 162 } |
166 | 163 |
167 | 164 |
168 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 165 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
169 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); | 166 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); |
170 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); | 167 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); |
171 | 168 |
172 // Visit any object pointers on the destination stack. | 169 // Visit any object pointers on the destination stack. |
173 if (dest_frame_is_allocated_) { | 170 if (dest_frame_is_allocated_) { |
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 Smi* offset, | 1302 Smi* offset, |
1306 TypedData* info, | 1303 TypedData* info, |
1307 Smi* reason) { | 1304 Smi* reason) { |
1308 intptr_t i = index * kEntrySize; | 1305 intptr_t i = index * kEntrySize; |
1309 *offset ^= table.At(i); | 1306 *offset ^= table.At(i); |
1310 *info ^= table.At(i + 1); | 1307 *info ^= table.At(i + 1); |
1311 *reason ^= table.At(i + 2); | 1308 *reason ^= table.At(i + 2); |
1312 } | 1309 } |
1313 | 1310 |
1314 } // namespace dart | 1311 } // namespace dart |
OLD | NEW |