| 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" |
| 12 #include "vm/code_patcher.h" | 13 #include "vm/code_patcher.h" |
| 13 #include "vm/compiler.h" | 14 #include "vm/compiler.h" |
| 14 #include "vm/compiler_stats.h" | 15 #include "vm/compiler_stats.h" |
| 15 #include "vm/class_finalizer.h" | 16 #include "vm/class_finalizer.h" |
| 16 #include "vm/dart.h" | 17 #include "vm/dart.h" |
| 17 #include "vm/dart_api_state.h" | 18 #include "vm/dart_api_state.h" |
| 18 #include "vm/dart_entry.h" | 19 #include "vm/dart_entry.h" |
| 19 #include "vm/debuginfo.h" | 20 #include "vm/debuginfo.h" |
| 20 #include "vm/double_conversion.h" | 21 #include "vm/double_conversion.h" |
| 21 #include "vm/exceptions.h" | 22 #include "vm/exceptions.h" |
| 22 #include "vm/growable_array.h" | 23 #include "vm/growable_array.h" |
| 23 #include "vm/heap.h" | 24 #include "vm/heap.h" |
| 24 #include "vm/object_store.h" | 25 #include "vm/object_store.h" |
| 25 #include "vm/parser.h" | 26 #include "vm/parser.h" |
| 26 #include "vm/runtime_entry.h" | 27 #include "vm/runtime_entry.h" |
| 27 #include "vm/scopes.h" | 28 #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 5520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5559 } | 5559 } |
| 5560 #endif // DEBUG | 5560 #endif // DEBUG |
| 5561 } | 5561 } |
| 5562 | 5562 |
| 5563 | 5563 |
| 5564 void Stackmap::SetCode(const Code& code) const { | 5564 void Stackmap::SetCode(const Code& code) const { |
| 5565 StorePointer(&raw_ptr()->code_, code.raw()); | 5565 StorePointer(&raw_ptr()->code_, code.raw()); |
| 5566 } | 5566 } |
| 5567 | 5567 |
| 5568 | 5568 |
| 5569 // Return the bit offset of the highest bit set. |
| 5570 intptr_t Stackmap::Maximum() const { |
| 5571 intptr_t bound = SizeInBits(); |
| 5572 for (intptr_t i = (bound - 1); i >= 0; i--) { |
| 5573 if (IsObject(i)) return i; |
| 5574 } |
| 5575 return kNoMaximum; |
| 5576 } |
| 5577 |
| 5578 |
| 5579 // Return the bit offset of the lowest bit set. |
| 5580 intptr_t Stackmap::Minimum() const { |
| 5581 intptr_t bound = SizeInBits(); |
| 5582 for (intptr_t i = 0; i < bound; i++) { |
| 5583 if (IsObject(i)) return i; |
| 5584 } |
| 5585 return kNoMinimum; |
| 5586 } |
| 5587 |
| 5588 |
| 5569 bool Stackmap::GetBit(intptr_t bit_offset) const { | 5589 bool Stackmap::GetBit(intptr_t bit_offset) const { |
| 5570 ASSERT(InRange(bit_offset)); | 5590 ASSERT(InRange(bit_offset)); |
| 5571 int byte_offset = bit_offset >> kBitsPerByteLog2; | 5591 int byte_offset = bit_offset >> kBitsPerByteLog2; |
| 5572 int bit_remainder = bit_offset & (kBitsPerByte - 1); | 5592 int bit_remainder = bit_offset & (kBitsPerByte - 1); |
| 5573 uint8_t byte_mask = 1U << bit_remainder; | 5593 uint8_t byte_mask = 1U << bit_remainder; |
| 5574 uint8_t byte = raw_ptr()->data_[byte_offset]; | 5594 uint8_t byte = raw_ptr()->data_[byte_offset]; |
| 5575 return (byte & byte_mask); | 5595 return (byte & byte_mask); |
| 5576 } | 5596 } |
| 5577 | 5597 |
| 5578 | 5598 |
| 5579 void Stackmap::SetBit(intptr_t bit_offset, bool value) const { | 5599 void Stackmap::SetBit(intptr_t bit_offset, bool value) const { |
| 5580 ASSERT(InRange(bit_offset)); | 5600 ASSERT(InRange(bit_offset)); |
| 5581 int byte_offset = bit_offset >> kBitsPerByteLog2; | 5601 int byte_offset = bit_offset >> kBitsPerByteLog2; |
| 5582 int bit_remainder = bit_offset & (kBitsPerByte - 1); | 5602 int bit_remainder = bit_offset & (kBitsPerByte - 1); |
| 5583 uint8_t byte_mask = 1U << bit_remainder; | 5603 uint8_t byte_mask = 1U << bit_remainder; |
| 5584 uint8_t* byte_addr = &(raw_ptr()->data_[byte_offset]); | 5604 uint8_t* byte_addr = &(raw_ptr()->data_[byte_offset]); |
| 5585 if (value) { | 5605 if (value) { |
| 5586 *byte_addr |= byte_mask; | 5606 *byte_addr |= byte_mask; |
| 5587 } else { | 5607 } else { |
| 5588 *byte_addr &= ~byte_mask; | 5608 *byte_addr &= ~byte_mask; |
| 5589 } | 5609 } |
| 5590 } | 5610 } |
| 5591 | 5611 |
| 5592 | 5612 |
| 5593 RawStackmap* Stackmap::New(uword pc_offset, BitmapBuilder* bmap) { | 5613 RawStackmap* Stackmap::New(uword pc, const Code& code, BitmapBuilder* bmap) { |
| 5594 const Class& cls = Class::Handle(Object::stackmap_class()); | 5614 const Class& cls = Class::Handle(Object::stackmap_class()); |
| 5595 ASSERT(!cls.IsNull()); | 5615 ASSERT(!cls.IsNull()); |
| 5596 ASSERT(bmap != NULL); | 5616 ASSERT(bmap != NULL); |
| 5597 Stackmap& result = Stackmap::Handle(); | 5617 Stackmap& result = Stackmap::Handle(); |
| 5598 intptr_t size = bmap->SizeInBytes(); | 5618 intptr_t size = bmap->SizeInBytes(); |
| 5599 { | 5619 { |
| 5600 // Stackmap data objects are associated with a code object, allocate them | 5620 // Stackmap data objects are associated with a code object, allocate them |
| 5601 // in old generation. | 5621 // in old generation. |
| 5602 RawObject* raw = | 5622 RawObject* raw = |
| 5603 Object::Allocate(cls, Stackmap::InstanceSize(size), Heap::kOld); | 5623 Object::Allocate(cls, Stackmap::InstanceSize(size), Heap::kOld); |
| 5604 NoGCScope no_gc; | 5624 NoGCScope no_gc; |
| 5605 result ^= raw; | 5625 result ^= raw; |
| 5606 result.set_bitmap_size_in_bytes(size); | 5626 result.set_bitmap_size_in_bytes(size); |
| 5607 } | 5627 } |
| 5608 result.SetPC(pc_offset); | 5628 result.set_pc(pc); |
| 5629 result.set_code(code); |
| 5609 intptr_t bound = bmap->SizeInBits(); | 5630 intptr_t bound = bmap->SizeInBits(); |
| 5610 for (intptr_t i = 0; i < bound; i++) { | 5631 for (intptr_t i = 0; i < bound; i++) { |
| 5611 result.SetBit(i, bmap->Get(i)); | 5632 result.SetBit(i, bmap->Get(i)); |
| 5612 } | 5633 } |
| 5613 result.SetMinBitOffset(bmap->Minimum()); | |
| 5614 result.SetMaxBitOffset(bmap->Maximum()); | |
| 5615 return result.raw(); | 5634 return result.raw(); |
| 5616 } | 5635 } |
| 5617 | 5636 |
| 5618 | 5637 |
| 5619 void Stackmap::set_bitmap_size_in_bytes(intptr_t value) const { | 5638 void Stackmap::set_bitmap_size_in_bytes(intptr_t value) const { |
| 5620 // This is only safe because we create a new Smi, which does not cause | 5639 // This is only safe because we create a new Smi, which does not cause |
| 5621 // heap allocation. | 5640 // heap allocation. |
| 5622 raw_ptr()->bitmap_size_in_bytes_ = Smi::New(value); | 5641 raw_ptr()->bitmap_size_in_bytes_ = Smi::New(value); |
| 5623 } | 5642 } |
| 5624 | 5643 |
| 5625 | 5644 |
| 5645 void Stackmap::set_pc(uword value) const { |
| 5646 raw_ptr()->pc_ = value; |
| 5647 } |
| 5648 |
| 5649 |
| 5650 void Stackmap::set_code(const Code& code) const { |
| 5651 StorePointer(&raw_ptr()->code_, code.raw()); |
| 5652 } |
| 5653 |
| 5654 |
| 5626 const char* Stackmap::ToCString() const { | 5655 const char* Stackmap::ToCString() const { |
| 5627 if (IsNull()) { | 5656 if (IsNull()) { |
| 5628 return "{null}"; | 5657 return "{null}"; |
| 5629 } else { | 5658 } else { |
| 5630 intptr_t index = OS::SNPrint(NULL, 0, "0x%lx { ", PC()); | 5659 intptr_t index = OS::SNPrint(NULL, 0, "0x%lx { ", PC()); |
| 5631 intptr_t alloc_size = | 5660 intptr_t alloc_size = index + ((Maximum() + 1) * 2) + 2; // "{ 1 0 .... }". |
| 5632 index + ((MaximumBitOffset() + 1) * 2) + 2; // "{ 1 0 .... }". | |
| 5633 Isolate* isolate = Isolate::Current(); | 5661 Isolate* isolate = Isolate::Current(); |
| 5634 char* chars = reinterpret_cast<char*>( | 5662 char* chars = reinterpret_cast<char*>( |
| 5635 isolate->current_zone()->Allocate(alloc_size)); | 5663 isolate->current_zone()->Allocate(alloc_size)); |
| 5636 index = OS::SNPrint(chars, alloc_size, "0x%lx { ", PC()); | 5664 index = OS::SNPrint(chars, alloc_size, "0x%lx { ", PC()); |
| 5637 for (intptr_t i = 0; i <= MaximumBitOffset(); i++) { | 5665 for (intptr_t i = 0; i <= Maximum(); i++) { |
| 5638 index += OS::SNPrint((chars + index), | 5666 index += OS::SNPrint((chars + index), |
| 5639 (alloc_size - index), | 5667 (alloc_size - index), |
| 5640 "%d ", | 5668 "%d ", |
| 5641 IsObject(i) ? 1 : 0); | 5669 IsObject(i) ? 1 : 0); |
| 5642 } | 5670 } |
| 5643 OS::SNPrint((chars + index), (alloc_size - index), "}"); | 5671 OS::SNPrint((chars + index), (alloc_size - index), "}"); |
| 5644 return chars; | 5672 return chars; |
| 5645 } | 5673 } |
| 5646 } | 5674 } |
| 5647 | 5675 |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5960 for (intptr_t i = 0; i < descriptors.Length(); i++) { | 5988 for (intptr_t i = 0; i < descriptors.Length(); i++) { |
| 5961 if (descriptors.DescriptorKind(i) == PcDescriptors::kIcCall) { | 5989 if (descriptors.DescriptorKind(i) == PcDescriptors::kIcCall) { |
| 5962 node_ids->Add(descriptors.NodeId(i)); | 5990 node_ids->Add(descriptors.NodeId(i)); |
| 5963 ic_data_obj = CodePatcher::GetInstanceCallIcDataAt(descriptors.PC(i)); | 5991 ic_data_obj = CodePatcher::GetInstanceCallIcDataAt(descriptors.PC(i)); |
| 5964 ic_data_objs.Add(ic_data_obj); | 5992 ic_data_objs.Add(ic_data_obj); |
| 5965 } | 5993 } |
| 5966 } | 5994 } |
| 5967 } | 5995 } |
| 5968 | 5996 |
| 5969 | 5997 |
| 5970 RawStackmap* Code::GetStackmap(uword pc, Array* maps, Stackmap* map) const { | |
| 5971 // This code is used only during iterating frames during a GC and hence | |
| 5972 // it should not in turn start a GC. | |
| 5973 NoGCScope no_gc; | |
| 5974 if (stackmaps() == Array::null()) { | |
| 5975 // No stack maps are present in the code object which means this | |
| 5976 // frame relies on tagged pointers. | |
| 5977 return Stackmap::null(); | |
| 5978 } | |
| 5979 // A stack map is present in the code object, use the stack map to visit | |
| 5980 // frame slots which are marked as having objects. | |
| 5981 RawStackmap* previous_map = Stackmap::null(); | |
| 5982 *maps = stackmaps(); | |
| 5983 *map = Stackmap::null(); | |
| 5984 for (intptr_t i = 0; i < maps->Length(); i++) { | |
| 5985 *map ^= maps->At(i); | |
| 5986 ASSERT(!map->IsNull()); | |
| 5987 if (map->PC() == pc) { | |
| 5988 break; // We found a stack map for this frame. | |
| 5989 } | |
| 5990 if (map->PC() > pc) { | |
| 5991 // We have not found a stackmap corresponding to the PC of this frame, | |
| 5992 // we will use the closest previous stack map. | |
| 5993 *map = previous_map; | |
| 5994 break; | |
| 5995 } | |
| 5996 previous_map = map->raw(); | |
| 5997 } | |
| 5998 return map->raw(); | |
| 5999 } | |
| 6000 | |
| 6001 | |
| 6002 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { | 5998 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { |
| 6003 ASSERT(num_variables >= 0); | 5999 ASSERT(num_variables >= 0); |
| 6004 | 6000 |
| 6005 const Class& context_class = Class::Handle(Object::context_class()); | 6001 const Class& context_class = Class::Handle(Object::context_class()); |
| 6006 Context& result = Context::Handle(); | 6002 Context& result = Context::Handle(); |
| 6007 { | 6003 { |
| 6008 RawObject* raw = Object::Allocate(context_class, | 6004 RawObject* raw = Object::Allocate(context_class, |
| 6009 Context::InstanceSize(num_variables), | 6005 Context::InstanceSize(num_variables), |
| 6010 space); | 6006 space); |
| 6011 NoGCScope no_gc; | 6007 NoGCScope no_gc; |
| (...skipping 2864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8876 } | 8872 } |
| 8877 | 8873 |
| 8878 | 8874 |
| 8879 void Stacktrace::set_pc_offset_array(const Array& pc_offset_array) const { | 8875 void Stacktrace::set_pc_offset_array(const Array& pc_offset_array) const { |
| 8880 StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); | 8876 StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); |
| 8881 } | 8877 } |
| 8882 | 8878 |
| 8883 | 8879 |
| 8884 void Stacktrace::SetupStacktrace(intptr_t index, | 8880 void Stacktrace::SetupStacktrace(intptr_t index, |
| 8885 const GrowableArray<uword>& frame_pcs) const { | 8881 const GrowableArray<uword>& frame_pcs) const { |
| 8886 Isolate* isolate = Isolate::Current(); | 8882 ASSERT(Isolate::Current() != NULL); |
| 8887 ASSERT(isolate != NULL); | 8883 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); |
| 8888 Function& function = Function::Handle(isolate, Function::null()); | 8884 ASSERT(code_index_table != NULL); |
| 8889 Code& code = Code::Handle(isolate, Code::null()); | 8885 Function& function = Function::Handle(); |
| 8890 Smi& pc_offset = Smi::Handle(isolate, Smi::New(0)); | 8886 Code& code = Code::Handle(); |
| 8887 Smi& pc_offset = Smi::Handle(); |
| 8891 const Array& function_array = Array::Handle(raw_ptr()->function_array_); | 8888 const Array& function_array = Array::Handle(raw_ptr()->function_array_); |
| 8892 const Array& code_array = Array::Handle(raw_ptr()->code_array_); | 8889 const Array& code_array = Array::Handle(raw_ptr()->code_array_); |
| 8893 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); | 8890 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); |
| 8894 for (intptr_t i = 0; i < frame_pcs.length(); i++) { | 8891 for (intptr_t i = 0; i < frame_pcs.length(); i++) { |
| 8895 code = StackFrame::LookupCode(isolate, frame_pcs[i]); | 8892 code = code_index_table->LookupCode(frame_pcs[i]); |
| 8896 ASSERT(!code.IsNull()); | 8893 ASSERT(!code.IsNull()); |
| 8897 function = code.function(); | 8894 function = code.function(); |
| 8898 function_array.SetAt((index + i), function); | 8895 function_array.SetAt((index + i), function); |
| 8899 code_array.SetAt((index + i), code); | 8896 code_array.SetAt((index + i), code); |
| 8900 pc_offset = Smi::New(frame_pcs[i] - code.EntryPoint()); | 8897 pc_offset = Smi::New(frame_pcs[i] - code.EntryPoint()); |
| 8901 pc_offset_array.SetAt((index + i), pc_offset); | 8898 pc_offset_array.SetAt((index + i), pc_offset); |
| 8902 } | 8899 } |
| 8903 } | 8900 } |
| 8904 | 8901 |
| 8905 | 8902 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9110 const String& str = String::Handle(pattern()); | 9107 const String& str = String::Handle(pattern()); |
| 9111 const char* format = "JSRegExp: pattern=%s flags=%s"; | 9108 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 9112 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 9109 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 9113 char* chars = reinterpret_cast<char*>( | 9110 char* chars = reinterpret_cast<char*>( |
| 9114 Isolate::Current()->current_zone()->Allocate(len + 1)); | 9111 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 9115 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 9112 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 9116 return chars; | 9113 return chars; |
| 9117 } | 9114 } |
| 9118 | 9115 |
| 9119 } // namespace dart | 9116 } // namespace dart |
| OLD | NEW |