OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/disassembler.h" | 5 #include "vm/disassembler.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 #include "vm/deopt_instructions.h" | 8 #include "vm/deopt_instructions.h" |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 #include "vm/il_printer.h" | 10 #include "vm/il_printer.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 human_buffer, sizeof(human_buffer), object, | 156 human_buffer, sizeof(human_buffer), object, |
157 pc); | 157 pc); |
158 pc += instruction_length; | 158 pc += instruction_length; |
159 } | 159 } |
160 } | 160 } |
161 | 161 |
162 | 162 |
163 void Disassembler::DisassembleCodeHelper(const char* function_fullname, | 163 void Disassembler::DisassembleCodeHelper(const char* function_fullname, |
164 const Code& code, | 164 const Code& code, |
165 bool optimized) { | 165 bool optimized) { |
166 LocalVarDescriptors& var_descriptors = LocalVarDescriptors::Handle(); | 166 Zone* zone = Thread::Current()->zone(); |
| 167 LocalVarDescriptors& var_descriptors = LocalVarDescriptors::Handle(zone); |
167 if (FLAG_print_variable_descriptors) { | 168 if (FLAG_print_variable_descriptors) { |
168 var_descriptors = code.GetLocalVarDescriptors(); | 169 var_descriptors = code.GetLocalVarDescriptors(); |
169 } | 170 } |
170 THR_Print("Code for %sfunction '%s' {\n", optimized ? "optimized " : "", | 171 THR_Print("Code for %sfunction '%s' {\n", optimized ? "optimized " : "", |
171 function_fullname); | 172 function_fullname); |
172 code.Disassemble(); | 173 code.Disassemble(); |
173 THR_Print("}\n"); | 174 THR_Print("}\n"); |
174 | 175 |
175 #if defined(TARGET_ARCH_IA32) | 176 #if defined(TARGET_ARCH_IA32) |
176 THR_Print("Pointer offsets for function: {\n"); | 177 THR_Print("Pointer offsets for function: {\n"); |
177 // Pointer offsets are stored in descending order. | 178 // Pointer offsets are stored in descending order. |
178 Object& obj = Object::Handle(); | 179 Object& obj = Object::Handle(zone); |
179 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { | 180 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { |
180 const uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart(); | 181 const uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart(); |
181 obj = *reinterpret_cast<RawObject**>(addr); | 182 obj = *reinterpret_cast<RawObject**>(addr); |
182 THR_Print(" %d : %#" Px " '%s'\n", code.GetPointerOffsetAt(i), addr, | 183 THR_Print(" %d : %#" Px " '%s'\n", code.GetPointerOffsetAt(i), addr, |
183 obj.ToCString()); | 184 obj.ToCString()); |
184 } | 185 } |
185 THR_Print("}\n"); | 186 THR_Print("}\n"); |
186 #else | 187 #else |
187 ASSERT(code.pointer_offsets_length() == 0); | 188 ASSERT(code.pointer_offsets_length() == 0); |
188 #endif | 189 #endif |
189 | 190 |
190 const ObjectPool& object_pool = ObjectPool::Handle(code.GetObjectPool()); | 191 const ObjectPool& object_pool = |
| 192 ObjectPool::Handle(zone, code.GetObjectPool()); |
191 object_pool.DebugPrint(); | 193 object_pool.DebugPrint(); |
192 | 194 |
193 THR_Print("PC Descriptors for function '%s' {\n", function_fullname); | 195 THR_Print("PC Descriptors for function '%s' {\n", function_fullname); |
194 PcDescriptors::PrintHeaderString(); | 196 PcDescriptors::PrintHeaderString(); |
195 const PcDescriptors& descriptors = | 197 const PcDescriptors& descriptors = |
196 PcDescriptors::Handle(code.pc_descriptors()); | 198 PcDescriptors::Handle(zone, code.pc_descriptors()); |
197 THR_Print("%s}\n", descriptors.ToCString()); | 199 THR_Print("%s}\n", descriptors.ToCString()); |
198 | 200 |
199 uword start = Instructions::Handle(code.instructions()).PayloadStart(); | 201 uword start = Instructions::Handle(zone, code.instructions()).PayloadStart(); |
200 const Array& deopt_table = Array::Handle(code.deopt_info_array()); | 202 const Array& deopt_table = Array::Handle(zone, code.deopt_info_array()); |
201 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); | 203 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); |
202 if (deopt_table_length > 0) { | 204 if (deopt_table_length > 0) { |
203 THR_Print("DeoptInfo: {\n"); | 205 THR_Print("DeoptInfo: {\n"); |
204 Smi& offset = Smi::Handle(); | 206 Smi& offset = Smi::Handle(zone); |
205 TypedData& info = TypedData::Handle(); | 207 TypedData& info = TypedData::Handle(zone); |
206 Smi& reason_and_flags = Smi::Handle(); | 208 Smi& reason_and_flags = Smi::Handle(zone); |
207 for (intptr_t i = 0; i < deopt_table_length; ++i) { | 209 for (intptr_t i = 0; i < deopt_table_length; ++i) { |
208 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason_and_flags); | 210 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason_and_flags); |
209 const intptr_t reason = | 211 const intptr_t reason = |
210 DeoptTable::ReasonField::decode(reason_and_flags.Value()); | 212 DeoptTable::ReasonField::decode(reason_and_flags.Value()); |
211 ASSERT((0 <= reason) && (reason < ICData::kDeoptNumReasons)); | 213 ASSERT((0 <= reason) && (reason < ICData::kDeoptNumReasons)); |
212 THR_Print( | 214 THR_Print( |
213 "%4" Pd ": 0x%" Px " %s (%s)\n", i, start + offset.Value(), | 215 "%4" Pd ": 0x%" Px " %s (%s)\n", i, start + offset.Value(), |
214 DeoptInfo::ToCString(deopt_table, info), | 216 DeoptInfo::ToCString(deopt_table, info), |
215 DeoptReasonToCString(static_cast<ICData::DeoptReasonId>(reason))); | 217 DeoptReasonToCString(static_cast<ICData::DeoptReasonId>(reason))); |
216 } | 218 } |
217 THR_Print("}\n"); | 219 THR_Print("}\n"); |
218 } | 220 } |
219 | 221 |
220 THR_Print("StackMaps for function '%s' {\n", function_fullname); | 222 THR_Print("StackMaps for function '%s' {\n", function_fullname); |
221 if (code.stackmaps() != Array::null()) { | 223 if (code.stackmaps() != Array::null()) { |
222 const Array& stackmap_table = Array::Handle(code.stackmaps()); | 224 const Array& stackmap_table = Array::Handle(zone, code.stackmaps()); |
223 StackMap& map = StackMap::Handle(); | 225 StackMap& map = StackMap::Handle(zone); |
224 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { | 226 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { |
225 map ^= stackmap_table.At(i); | 227 map ^= stackmap_table.At(i); |
226 THR_Print("%s\n", map.ToCString()); | 228 THR_Print("%s\n", map.ToCString()); |
227 } | 229 } |
228 } | 230 } |
229 THR_Print("}\n"); | 231 THR_Print("}\n"); |
230 | 232 |
231 if (FLAG_print_variable_descriptors) { | 233 if (FLAG_print_variable_descriptors) { |
232 THR_Print("Variable Descriptors for function '%s' {\n", function_fullname); | 234 THR_Print("Variable Descriptors for function '%s' {\n", function_fullname); |
233 intptr_t var_desc_length = | 235 intptr_t var_desc_length = |
234 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); | 236 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); |
235 String& var_name = String::Handle(); | 237 String& var_name = String::Handle(zone); |
236 for (intptr_t i = 0; i < var_desc_length; i++) { | 238 for (intptr_t i = 0; i < var_desc_length; i++) { |
237 var_name = var_descriptors.GetName(i); | 239 var_name = var_descriptors.GetName(i); |
238 RawLocalVarDescriptors::VarInfo var_info; | 240 RawLocalVarDescriptors::VarInfo var_info; |
239 var_descriptors.GetInfo(i, &var_info); | 241 var_descriptors.GetInfo(i, &var_info); |
240 const int8_t kind = var_info.kind(); | 242 const int8_t kind = var_info.kind(); |
241 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 243 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
242 THR_Print(" saved current CTX reg offset %d\n", var_info.index()); | 244 THR_Print(" saved current CTX reg offset %d\n", var_info.index()); |
243 } else { | 245 } else { |
244 if (kind == RawLocalVarDescriptors::kContextLevel) { | 246 if (kind == RawLocalVarDescriptors::kContextLevel) { |
245 THR_Print(" context level %d scope %d", var_info.index(), | 247 THR_Print(" context level %d scope %d", var_info.index(), |
246 var_info.scope_id); | 248 var_info.scope_id); |
247 } else if (kind == RawLocalVarDescriptors::kStackVar) { | 249 } else if (kind == RawLocalVarDescriptors::kStackVar) { |
248 THR_Print(" stack var '%s' offset %d", var_name.ToCString(), | 250 THR_Print(" stack var '%s' offset %d", var_name.ToCString(), |
249 var_info.index()); | 251 var_info.index()); |
250 } else { | 252 } else { |
251 ASSERT(kind == RawLocalVarDescriptors::kContextVar); | 253 ASSERT(kind == RawLocalVarDescriptors::kContextVar); |
252 THR_Print(" context var '%s' level %d offset %d", | 254 THR_Print(" context var '%s' level %d offset %d", |
253 var_name.ToCString(), var_info.scope_id, var_info.index()); | 255 var_name.ToCString(), var_info.scope_id, var_info.index()); |
254 } | 256 } |
255 THR_Print(" (valid %s-%s)\n", var_info.begin_pos.ToCString(), | 257 THR_Print(" (valid %s-%s)\n", var_info.begin_pos.ToCString(), |
256 var_info.end_pos.ToCString()); | 258 var_info.end_pos.ToCString()); |
257 } | 259 } |
258 } | 260 } |
259 THR_Print("}\n"); | 261 THR_Print("}\n"); |
260 } | 262 } |
261 | 263 |
262 THR_Print("Exception Handlers for function '%s' {\n", function_fullname); | 264 THR_Print("Exception Handlers for function '%s' {\n", function_fullname); |
263 const ExceptionHandlers& handlers = | 265 const ExceptionHandlers& handlers = |
264 ExceptionHandlers::Handle(code.exception_handlers()); | 266 ExceptionHandlers::Handle(zone, code.exception_handlers()); |
265 THR_Print("%s}\n", handlers.ToCString()); | 267 THR_Print("%s}\n", handlers.ToCString()); |
266 | 268 |
267 { | 269 { |
268 THR_Print("Static call target functions {\n"); | 270 THR_Print("Static call target functions {\n"); |
269 const Array& table = Array::Handle(code.static_calls_target_table()); | 271 const Array& table = Array::Handle(zone, code.static_calls_target_table()); |
270 Smi& offset = Smi::Handle(); | 272 Smi& offset = Smi::Handle(zone); |
271 Function& function = Function::Handle(); | 273 Function& function = Function::Handle(zone); |
272 Code& code = Code::Handle(); | 274 Code& code = Code::Handle(zone); |
273 for (intptr_t i = 0; i < table.Length(); | 275 for (intptr_t i = 0; i < table.Length(); |
274 i += Code::kSCallTableEntryLength) { | 276 i += Code::kSCallTableEntryLength) { |
275 offset ^= table.At(i + Code::kSCallTableOffsetEntry); | 277 offset ^= table.At(i + Code::kSCallTableOffsetEntry); |
276 function ^= table.At(i + Code::kSCallTableFunctionEntry); | 278 function ^= table.At(i + Code::kSCallTableFunctionEntry); |
277 code ^= table.At(i + Code::kSCallTableCodeEntry); | 279 code ^= table.At(i + Code::kSCallTableCodeEntry); |
278 if (function.IsNull()) { | 280 if (function.IsNull()) { |
279 Class& cls = Class::Handle(); | 281 Class& cls = Class::Handle(zone); |
280 cls ^= code.owner(); | 282 cls ^= code.owner(); |
281 if (cls.IsNull()) { | 283 if (cls.IsNull()) { |
282 THR_Print(" 0x%" Px ": %s, %p\n", start + offset.Value(), | 284 THR_Print(" 0x%" Px ": %s, %p\n", start + offset.Value(), |
283 code.Name(), code.raw()); | 285 code.QualifiedName(), code.raw()); |
284 } else { | 286 } else { |
285 THR_Print(" 0x%" Px ": allocation stub for %s, %p\n", | 287 THR_Print(" 0x%" Px ": allocation stub for %s, %p\n", |
286 start + offset.Value(), cls.ToCString(), code.raw()); | 288 start + offset.Value(), cls.ToCString(), code.raw()); |
287 } | 289 } |
288 } else { | 290 } else { |
289 THR_Print(" 0x%" Px ": %s, %p\n", start + offset.Value(), | 291 THR_Print(" 0x%" Px ": %s, %p\n", start + offset.Value(), |
290 function.ToFullyQualifiedCString(), code.raw()); | 292 function.ToFullyQualifiedCString(), code.raw()); |
291 } | 293 } |
292 } | 294 } |
293 THR_Print("}\n"); | 295 THR_Print("}\n"); |
(...skipping 11 matching lines...) Expand all Loading... |
305 const Code& code, | 307 const Code& code, |
306 bool optimized) { | 308 bool optimized) { |
307 const char* function_fullname = function.ToFullyQualifiedCString(); | 309 const char* function_fullname = function.ToFullyQualifiedCString(); |
308 DisassembleCodeHelper(function_fullname, code, optimized); | 310 DisassembleCodeHelper(function_fullname, code, optimized); |
309 } | 311 } |
310 | 312 |
311 | 313 |
312 #endif // !PRODUCT | 314 #endif // !PRODUCT |
313 | 315 |
314 } // namespace dart | 316 } // namespace dart |
OLD | NEW |