OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
11 #include "vm/code_generator.h" | 11 #include "vm/code_generator.h" |
12 #include "vm/code_index_table.h" | |
13 #include "vm/code_patcher.h" | 12 #include "vm/code_patcher.h" |
14 #include "vm/compiler.h" | 13 #include "vm/compiler.h" |
15 #include "vm/compiler_stats.h" | 14 #include "vm/compiler_stats.h" |
16 #include "vm/class_finalizer.h" | 15 #include "vm/class_finalizer.h" |
17 #include "vm/dart.h" | 16 #include "vm/dart.h" |
18 #include "vm/dart_api_state.h" | 17 #include "vm/dart_api_state.h" |
19 #include "vm/dart_entry.h" | 18 #include "vm/dart_entry.h" |
20 #include "vm/debuginfo.h" | 19 #include "vm/debuginfo.h" |
21 #include "vm/double_conversion.h" | 20 #include "vm/double_conversion.h" |
22 #include "vm/exceptions.h" | 21 #include "vm/exceptions.h" |
23 #include "vm/growable_array.h" | 22 #include "vm/growable_array.h" |
24 #include "vm/heap.h" | 23 #include "vm/heap.h" |
25 #include "vm/object_store.h" | 24 #include "vm/object_store.h" |
26 #include "vm/parser.h" | 25 #include "vm/parser.h" |
27 #include "vm/runtime_entry.h" | 26 #include "vm/runtime_entry.h" |
28 #include "vm/scopes.h" | 27 #include "vm/scopes.h" |
| 28 #include "vm/stack_frame.h" |
29 #include "vm/timer.h" | 29 #include "vm/timer.h" |
30 #include "vm/unicode.h" | 30 #include "vm/unicode.h" |
31 | 31 |
32 namespace dart { | 32 namespace dart { |
33 | 33 |
34 DEFINE_FLAG(bool, generate_gdb_symbols, false, | 34 DEFINE_FLAG(bool, generate_gdb_symbols, false, |
35 "Generate symbols of generated dart functions for debugging with GDB"); | 35 "Generate symbols of generated dart functions for debugging with GDB"); |
36 DECLARE_FLAG(bool, trace_compiler); | 36 DECLARE_FLAG(bool, trace_compiler); |
37 DECLARE_FLAG(bool, enable_type_checks); | 37 DECLARE_FLAG(bool, enable_type_checks); |
38 | 38 |
(...skipping 5397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5436 } | 5436 } |
5437 #endif // DEBUG | 5437 #endif // DEBUG |
5438 } | 5438 } |
5439 | 5439 |
5440 | 5440 |
5441 void Stackmap::SetCode(const Code& code) const { | 5441 void Stackmap::SetCode(const Code& code) const { |
5442 StorePointer(&raw_ptr()->code_, code.raw()); | 5442 StorePointer(&raw_ptr()->code_, code.raw()); |
5443 } | 5443 } |
5444 | 5444 |
5445 | 5445 |
5446 // Return the bit offset of the highest bit set. | |
5447 intptr_t Stackmap::Maximum() const { | |
5448 intptr_t bound = SizeInBits(); | |
5449 for (intptr_t i = (bound - 1); i >= 0; i--) { | |
5450 if (IsObject(i)) return i; | |
5451 } | |
5452 return kNoMaximum; | |
5453 } | |
5454 | |
5455 | |
5456 // Return the bit offset of the lowest bit set. | |
5457 intptr_t Stackmap::Minimum() const { | |
5458 intptr_t bound = SizeInBits(); | |
5459 for (intptr_t i = 0; i < bound; i++) { | |
5460 if (IsObject(i)) return i; | |
5461 } | |
5462 return kNoMinimum; | |
5463 } | |
5464 | |
5465 | |
5466 bool Stackmap::GetBit(intptr_t bit_offset) const { | 5446 bool Stackmap::GetBit(intptr_t bit_offset) const { |
5467 ASSERT(InRange(bit_offset)); | 5447 ASSERT(InRange(bit_offset)); |
5468 int byte_offset = bit_offset >> kBitsPerByteLog2; | 5448 int byte_offset = bit_offset >> kBitsPerByteLog2; |
5469 int bit_remainder = bit_offset & (kBitsPerByte - 1); | 5449 int bit_remainder = bit_offset & (kBitsPerByte - 1); |
5470 uint8_t byte_mask = 1U << bit_remainder; | 5450 uint8_t byte_mask = 1U << bit_remainder; |
5471 uint8_t byte = raw_ptr()->data_[byte_offset]; | 5451 uint8_t byte = raw_ptr()->data_[byte_offset]; |
5472 return (byte & byte_mask); | 5452 return (byte & byte_mask); |
5473 } | 5453 } |
5474 | 5454 |
5475 | 5455 |
5476 void Stackmap::SetBit(intptr_t bit_offset, bool value) const { | 5456 void Stackmap::SetBit(intptr_t bit_offset, bool value) const { |
5477 ASSERT(InRange(bit_offset)); | 5457 ASSERT(InRange(bit_offset)); |
5478 int byte_offset = bit_offset >> kBitsPerByteLog2; | 5458 int byte_offset = bit_offset >> kBitsPerByteLog2; |
5479 int bit_remainder = bit_offset & (kBitsPerByte - 1); | 5459 int bit_remainder = bit_offset & (kBitsPerByte - 1); |
5480 uint8_t byte_mask = 1U << bit_remainder; | 5460 uint8_t byte_mask = 1U << bit_remainder; |
5481 uint8_t* byte_addr = &(raw_ptr()->data_[byte_offset]); | 5461 uint8_t* byte_addr = &(raw_ptr()->data_[byte_offset]); |
5482 if (value) { | 5462 if (value) { |
5483 *byte_addr |= byte_mask; | 5463 *byte_addr |= byte_mask; |
5484 } else { | 5464 } else { |
5485 *byte_addr &= ~byte_mask; | 5465 *byte_addr &= ~byte_mask; |
5486 } | 5466 } |
5487 } | 5467 } |
5488 | 5468 |
5489 | 5469 |
5490 RawStackmap* Stackmap::New(uword pc, const Code& code, BitmapBuilder* bmap) { | 5470 RawStackmap* Stackmap::New(uword pc_offset, BitmapBuilder* bmap) { |
5491 const Class& cls = Class::Handle(Object::stackmap_class()); | 5471 const Class& cls = Class::Handle(Object::stackmap_class()); |
5492 ASSERT(!cls.IsNull()); | 5472 ASSERT(!cls.IsNull()); |
5493 ASSERT(bmap != NULL); | 5473 ASSERT(bmap != NULL); |
5494 Stackmap& result = Stackmap::Handle(); | 5474 Stackmap& result = Stackmap::Handle(); |
5495 intptr_t size = bmap->SizeInBytes(); | 5475 intptr_t size = bmap->SizeInBytes(); |
5496 { | 5476 { |
5497 // Stackmap data objects are associated with a code object, allocate them | 5477 // Stackmap data objects are associated with a code object, allocate them |
5498 // in old generation. | 5478 // in old generation. |
5499 RawObject* raw = | 5479 RawObject* raw = |
5500 Object::Allocate(cls, Stackmap::InstanceSize(size), Heap::kOld); | 5480 Object::Allocate(cls, Stackmap::InstanceSize(size), Heap::kOld); |
5501 NoGCScope no_gc; | 5481 NoGCScope no_gc; |
5502 result ^= raw; | 5482 result ^= raw; |
5503 result.set_bitmap_size_in_bytes(size); | 5483 result.set_bitmap_size_in_bytes(size); |
5504 } | 5484 } |
5505 result.set_pc(pc); | 5485 result.SetPC(pc_offset); |
5506 result.set_code(code); | |
5507 intptr_t bound = bmap->SizeInBits(); | 5486 intptr_t bound = bmap->SizeInBits(); |
5508 for (intptr_t i = 0; i < bound; i++) { | 5487 for (intptr_t i = 0; i < bound; i++) { |
5509 result.SetBit(i, bmap->Get(i)); | 5488 result.SetBit(i, bmap->Get(i)); |
5510 } | 5489 } |
| 5490 result.SetMinBitOffset(bmap->Minimum()); |
| 5491 result.SetMaxBitOffset(bmap->Maximum()); |
5511 return result.raw(); | 5492 return result.raw(); |
5512 } | 5493 } |
5513 | 5494 |
5514 | 5495 |
5515 void Stackmap::set_bitmap_size_in_bytes(intptr_t value) const { | 5496 void Stackmap::set_bitmap_size_in_bytes(intptr_t value) const { |
5516 // This is only safe because we create a new Smi, which does not cause | 5497 // This is only safe because we create a new Smi, which does not cause |
5517 // heap allocation. | 5498 // heap allocation. |
5518 raw_ptr()->bitmap_size_in_bytes_ = Smi::New(value); | 5499 raw_ptr()->bitmap_size_in_bytes_ = Smi::New(value); |
5519 } | 5500 } |
5520 | 5501 |
5521 | 5502 |
5522 void Stackmap::set_pc(uword value) const { | |
5523 raw_ptr()->pc_ = value; | |
5524 } | |
5525 | |
5526 | |
5527 void Stackmap::set_code(const Code& code) const { | |
5528 StorePointer(&raw_ptr()->code_, code.raw()); | |
5529 } | |
5530 | |
5531 | |
5532 const char* Stackmap::ToCString() const { | 5503 const char* Stackmap::ToCString() const { |
5533 if (IsNull()) { | 5504 if (IsNull()) { |
5534 return "{null}"; | 5505 return "{null}"; |
5535 } else { | 5506 } else { |
5536 intptr_t index = OS::SNPrint(NULL, 0, "0x%lx { ", PC()); | 5507 intptr_t index = OS::SNPrint(NULL, 0, "0x%lx { ", PC()); |
5537 intptr_t alloc_size = index + ((Maximum() + 1) * 2) + 2; // "{ 1 0 .... }". | 5508 intptr_t alloc_size = |
| 5509 index + ((MaximumBitOffset() + 1) * 2) + 2; // "{ 1 0 .... }". |
5538 Isolate* isolate = Isolate::Current(); | 5510 Isolate* isolate = Isolate::Current(); |
5539 char* chars = reinterpret_cast<char*>( | 5511 char* chars = reinterpret_cast<char*>( |
5540 isolate->current_zone()->Allocate(alloc_size)); | 5512 isolate->current_zone()->Allocate(alloc_size)); |
5541 index = OS::SNPrint(chars, alloc_size, "0x%lx { ", PC()); | 5513 index = OS::SNPrint(chars, alloc_size, "0x%lx { ", PC()); |
5542 for (intptr_t i = 0; i <= Maximum(); i++) { | 5514 for (intptr_t i = 0; i <= MaximumBitOffset(); i++) { |
5543 index += OS::SNPrint((chars + index), | 5515 index += OS::SNPrint((chars + index), |
5544 (alloc_size - index), | 5516 (alloc_size - index), |
5545 "%d ", | 5517 "%d ", |
5546 IsObject(i) ? 1 : 0); | 5518 IsObject(i) ? 1 : 0); |
5547 } | 5519 } |
5548 OS::SNPrint((chars + index), (alloc_size - index), "}"); | 5520 OS::SNPrint((chars + index), (alloc_size - index), "}"); |
5549 return chars; | 5521 return chars; |
5550 } | 5522 } |
5551 } | 5523 } |
5552 | 5524 |
(...skipping 3181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8734 } | 8706 } |
8735 | 8707 |
8736 | 8708 |
8737 void Stacktrace::set_pc_offset_array(const Array& pc_offset_array) const { | 8709 void Stacktrace::set_pc_offset_array(const Array& pc_offset_array) const { |
8738 StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); | 8710 StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); |
8739 } | 8711 } |
8740 | 8712 |
8741 | 8713 |
8742 void Stacktrace::SetupStacktrace(intptr_t index, | 8714 void Stacktrace::SetupStacktrace(intptr_t index, |
8743 const GrowableArray<uword>& frame_pcs) const { | 8715 const GrowableArray<uword>& frame_pcs) const { |
8744 ASSERT(Isolate::Current() != NULL); | 8716 Isolate* isolate = Isolate::Current(); |
8745 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); | 8717 ASSERT(isolate != NULL); |
8746 ASSERT(code_index_table != NULL); | 8718 Function& function = Function::Handle(isolate, Function::null()); |
8747 Function& function = Function::Handle(); | 8719 Code& code = Code::Handle(isolate, Code::null()); |
8748 Code& code = Code::Handle(); | 8720 Smi& pc_offset = Smi::Handle(isolate, Smi::New(0)); |
8749 Smi& pc_offset = Smi::Handle(); | |
8750 const Array& function_array = Array::Handle(raw_ptr()->function_array_); | 8721 const Array& function_array = Array::Handle(raw_ptr()->function_array_); |
8751 const Array& code_array = Array::Handle(raw_ptr()->code_array_); | 8722 const Array& code_array = Array::Handle(raw_ptr()->code_array_); |
8752 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); | 8723 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); |
8753 for (intptr_t i = 0; i < frame_pcs.length(); i++) { | 8724 for (intptr_t i = 0; i < frame_pcs.length(); i++) { |
8754 code = code_index_table->LookupCode(frame_pcs[i]); | 8725 code = StackFrame::LookupCode(isolate, frame_pcs[i]); |
8755 ASSERT(!code.IsNull()); | 8726 ASSERT(!code.IsNull()); |
8756 function = code.function(); | 8727 function = code.function(); |
8757 function_array.SetAt((index + i), function); | 8728 function_array.SetAt((index + i), function); |
8758 code_array.SetAt((index + i), code); | 8729 code_array.SetAt((index + i), code); |
8759 pc_offset = Smi::New(frame_pcs[i] - code.EntryPoint()); | 8730 pc_offset = Smi::New(frame_pcs[i] - code.EntryPoint()); |
8760 pc_offset_array.SetAt((index + i), pc_offset); | 8731 pc_offset_array.SetAt((index + i), pc_offset); |
8761 } | 8732 } |
8762 } | 8733 } |
8763 | 8734 |
8764 | 8735 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8969 const String& str = String::Handle(pattern()); | 8940 const String& str = String::Handle(pattern()); |
8970 const char* format = "JSRegExp: pattern=%s flags=%s"; | 8941 const char* format = "JSRegExp: pattern=%s flags=%s"; |
8971 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 8942 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
8972 char* chars = reinterpret_cast<char*>( | 8943 char* chars = reinterpret_cast<char*>( |
8973 Isolate::Current()->current_zone()->Allocate(len + 1)); | 8944 Isolate::Current()->current_zone()->Allocate(len + 1)); |
8974 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 8945 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
8975 return chars; | 8946 return chars; |
8976 } | 8947 } |
8977 | 8948 |
8978 } // namespace dart | 8949 } // namespace dart |
OLD | NEW |