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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/become.h" | 10 #include "vm/become.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 #include "vm/runtime_entry.h" | 38 #include "vm/runtime_entry.h" |
39 #include "vm/scopes.h" | 39 #include "vm/scopes.h" |
40 #include "vm/stack_frame.h" | 40 #include "vm/stack_frame.h" |
41 #include "vm/symbols.h" | 41 #include "vm/symbols.h" |
42 #include "vm/tags.h" | 42 #include "vm/tags.h" |
43 #include "vm/thread_registry.h" | 43 #include "vm/thread_registry.h" |
44 #include "vm/timeline.h" | 44 #include "vm/timeline.h" |
45 #include "vm/timer.h" | 45 #include "vm/timer.h" |
46 #include "vm/type_table.h" | 46 #include "vm/type_table.h" |
47 #include "vm/unicode.h" | 47 #include "vm/unicode.h" |
48 #include "vm/verified_memory.h" | |
49 #include "vm/weak_code.h" | 48 #include "vm/weak_code.h" |
50 | 49 |
51 namespace dart { | 50 namespace dart { |
52 | 51 |
53 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, | 52 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, |
54 "Huge method cutoff in unoptimized code size (in bytes)."); | 53 "Huge method cutoff in unoptimized code size (in bytes)."); |
55 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, | 54 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, |
56 "Huge method cutoff in tokens: Disables optimizations for huge methods."); | 55 "Huge method cutoff in tokens: Disables optimizations for huge methods."); |
57 DEFINE_FLAG(bool, overlap_type_arguments, true, | 56 DEFINE_FLAG(bool, overlap_type_arguments, true, |
58 "When possible, partially or fully overlap the type arguments of a type " | 57 "When possible, partially or fully overlap the type arguments of a type " |
(...skipping 999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 uword old_tags; | 1057 uword old_tags; |
1059 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. | 1058 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. |
1060 do { | 1059 do { |
1061 old_tags = tags; | 1060 old_tags = tags; |
1062 tags = AtomicOperations::CompareAndSwapWord( | 1061 tags = AtomicOperations::CompareAndSwapWord( |
1063 &raw->ptr()->tags_, old_tags, new_tags); | 1062 &raw->ptr()->tags_, old_tags, new_tags); |
1064 } while (tags != old_tags); | 1063 } while (tags != old_tags); |
1065 | 1064 |
1066 intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0)); | 1065 intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0)); |
1067 ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size); | 1066 ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size); |
1068 raw->InitializeSmi(&(raw->ptr()->length_), Smi::New(leftover_len)); | 1067 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len)); |
1069 } else { | 1068 } else { |
1070 // Update the leftover space as a basic object. | 1069 // Update the leftover space as a basic object. |
1071 ASSERT(leftover_size == Object::InstanceSize()); | 1070 ASSERT(leftover_size == Object::InstanceSize()); |
1072 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr)); | 1071 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr)); |
1073 uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0); | 1072 uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0); |
1074 new_tags = RawObject::SizeTag::update(leftover_size, new_tags); | 1073 new_tags = RawObject::SizeTag::update(leftover_size, new_tags); |
1075 uword tags = raw->ptr()->tags_; | 1074 uword tags = raw->ptr()->tags_; |
1076 uword old_tags; | 1075 uword old_tags; |
1077 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. | 1076 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. |
1078 do { | 1077 do { |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1792 *reinterpret_cast<uword*>(cur) = initial_value; | 1791 *reinterpret_cast<uword*>(cur) = initial_value; |
1793 cur += kWordSize; | 1792 cur += kWordSize; |
1794 } | 1793 } |
1795 uword tags = 0; | 1794 uword tags = 0; |
1796 ASSERT(class_id != kIllegalCid); | 1795 ASSERT(class_id != kIllegalCid); |
1797 tags = RawObject::ClassIdTag::update(class_id, tags); | 1796 tags = RawObject::ClassIdTag::update(class_id, tags); |
1798 tags = RawObject::SizeTag::update(size, tags); | 1797 tags = RawObject::SizeTag::update(size, tags); |
1799 tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags); | 1798 tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags); |
1800 reinterpret_cast<RawObject*>(address)->tags_ = tags; | 1799 reinterpret_cast<RawObject*>(address)->tags_ = tags; |
1801 ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags)); | 1800 ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags)); |
1802 VerifiedMemory::Accept(address, size); | |
1803 } | 1801 } |
1804 | 1802 |
1805 | 1803 |
1806 void Object::CheckHandle() const { | 1804 void Object::CheckHandle() const { |
1807 #if defined(DEBUG) | 1805 #if defined(DEBUG) |
1808 if (raw_ != Object::null()) { | 1806 if (raw_ != Object::null()) { |
1809 if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) { | 1807 if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) { |
1810 ASSERT(vtable() == Smi::handle_vtable_); | 1808 ASSERT(vtable() == Smi::handle_vtable_); |
1811 return; | 1809 return; |
1812 } | 1810 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1911 // TODO(koda): This will trip when we start allocating black. | 1909 // TODO(koda): This will trip when we start allocating black. |
1912 // Revisit code below at that point, to account for the new write barrier. | 1910 // Revisit code below at that point, to account for the new write barrier. |
1913 ASSERT(!raw_clone->IsMarked()); | 1911 ASSERT(!raw_clone->IsMarked()); |
1914 // Copy the body of the original into the clone. | 1912 // Copy the body of the original into the clone. |
1915 uword orig_addr = RawObject::ToAddr(orig.raw()); | 1913 uword orig_addr = RawObject::ToAddr(orig.raw()); |
1916 uword clone_addr = RawObject::ToAddr(raw_clone); | 1914 uword clone_addr = RawObject::ToAddr(raw_clone); |
1917 static const intptr_t kHeaderSizeInBytes = sizeof(RawObject); | 1915 static const intptr_t kHeaderSizeInBytes = sizeof(RawObject); |
1918 memmove(reinterpret_cast<uint8_t*>(clone_addr + kHeaderSizeInBytes), | 1916 memmove(reinterpret_cast<uint8_t*>(clone_addr + kHeaderSizeInBytes), |
1919 reinterpret_cast<uint8_t*>(orig_addr + kHeaderSizeInBytes), | 1917 reinterpret_cast<uint8_t*>(orig_addr + kHeaderSizeInBytes), |
1920 size - kHeaderSizeInBytes); | 1918 size - kHeaderSizeInBytes); |
1921 VerifiedMemory::Accept(clone_addr, size); | |
1922 // Add clone to store buffer, if needed. | 1919 // Add clone to store buffer, if needed. |
1923 if (!raw_clone->IsOldObject()) { | 1920 if (!raw_clone->IsOldObject()) { |
1924 // No need to remember an object in new space. | 1921 // No need to remember an object in new space. |
1925 return raw_clone; | 1922 return raw_clone; |
1926 } else if (orig.raw()->IsOldObject() && !orig.raw()->IsRemembered()) { | 1923 } else if (orig.raw()->IsOldObject() && !orig.raw()->IsRemembered()) { |
1927 // Old original doesn't need to be remembered, so neither does the clone. | 1924 // Old original doesn't need to be remembered, so neither does the clone. |
1928 return raw_clone; | 1925 return raw_clone; |
1929 } | 1926 } |
1930 StoreBufferUpdateVisitor visitor(Thread::Current(), raw_clone); | 1927 StoreBufferUpdateVisitor visitor(Thread::Current(), raw_clone); |
1931 raw_clone->VisitPointers(&visitor); | 1928 raw_clone->VisitPointers(&visitor); |
(...skipping 12099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14031 Instructions& instrs = | 14028 Instructions& instrs = |
14032 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); | 14029 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); |
14033 INC_STAT(Thread::Current(), total_instr_size, assembler->CodeSize()); | 14030 INC_STAT(Thread::Current(), total_instr_size, assembler->CodeSize()); |
14034 INC_STAT(Thread::Current(), total_code_size, assembler->CodeSize()); | 14031 INC_STAT(Thread::Current(), total_code_size, assembler->CodeSize()); |
14035 | 14032 |
14036 // Copy the instructions into the instruction area and apply all fixups. | 14033 // Copy the instructions into the instruction area and apply all fixups. |
14037 // Embedded pointers are still in handles at this point. | 14034 // Embedded pointers are still in handles at this point. |
14038 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), | 14035 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), |
14039 instrs.size()); | 14036 instrs.size()); |
14040 assembler->FinalizeInstructions(region); | 14037 assembler->FinalizeInstructions(region); |
14041 VerifiedMemory::Accept(region.start(), region.size()); | |
14042 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); | 14038 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); |
14043 | 14039 |
14044 code.set_compile_timestamp(OS::GetCurrentMonotonicMicros()); | 14040 code.set_compile_timestamp(OS::GetCurrentMonotonicMicros()); |
14045 #ifndef PRODUCT | 14041 #ifndef PRODUCT |
14046 CodeObservers::NotifyAll(name, | 14042 CodeObservers::NotifyAll(name, |
14047 instrs.EntryPoint(), | 14043 instrs.EntryPoint(), |
14048 assembler->prologue_offset(), | 14044 assembler->prologue_offset(), |
14049 instrs.size(), | 14045 instrs.size(), |
14050 optimized); | 14046 optimized); |
14051 #endif | 14047 #endif |
(...skipping 7282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21334 // This should be caught before we reach here. | 21330 // This should be caught before we reach here. |
21335 FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len); | 21331 FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len); |
21336 } | 21332 } |
21337 { | 21333 { |
21338 RawArray* raw = reinterpret_cast<RawArray*>( | 21334 RawArray* raw = reinterpret_cast<RawArray*>( |
21339 Object::Allocate(class_id, | 21335 Object::Allocate(class_id, |
21340 Array::InstanceSize(len), | 21336 Array::InstanceSize(len), |
21341 space)); | 21337 space)); |
21342 NoSafepointScope no_safepoint; | 21338 NoSafepointScope no_safepoint; |
21343 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len)); | 21339 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len)); |
21344 VerifiedMemory::Accept(reinterpret_cast<uword>(raw->ptr()), | |
21345 Array::InstanceSize(len)); | |
21346 return raw; | 21340 return raw; |
21347 } | 21341 } |
21348 } | 21342 } |
21349 | 21343 |
21350 | 21344 |
21351 RawArray* Array::Slice(intptr_t start, | 21345 RawArray* Array::Slice(intptr_t start, |
21352 intptr_t count, | 21346 intptr_t count, |
21353 bool with_type_argument) const { | 21347 bool with_type_argument) const { |
21354 // TODO(vegorov) introduce an array allocation method that fills newly | 21348 // TODO(vegorov) introduce an array allocation method that fills newly |
21355 // allocated array with values from the given source array instead of | 21349 // allocated array with values from the given source array instead of |
(...skipping 1318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22674 return UserTag::null(); | 22668 return UserTag::null(); |
22675 } | 22669 } |
22676 | 22670 |
22677 | 22671 |
22678 const char* UserTag::ToCString() const { | 22672 const char* UserTag::ToCString() const { |
22679 const String& tag_label = String::Handle(label()); | 22673 const String& tag_label = String::Handle(label()); |
22680 return tag_label.ToCString(); | 22674 return tag_label.ToCString(); |
22681 } | 22675 } |
22682 | 22676 |
22683 } // namespace dart | 22677 } // namespace dart |
OLD | NEW |