| 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 |