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/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 9983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9994 } | 9994 } |
9995 ASSERT(Object::code_class() != Class::null()); | 9995 ASSERT(Object::code_class() != Class::null()); |
9996 Code& result = Code::Handle(); | 9996 Code& result = Code::Handle(); |
9997 { | 9997 { |
9998 uword size = Code::InstanceSize(pointer_offsets_length); | 9998 uword size = Code::InstanceSize(pointer_offsets_length); |
9999 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); | 9999 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); |
10000 NoGCScope no_gc; | 10000 NoGCScope no_gc; |
10001 result ^= raw; | 10001 result ^= raw; |
10002 result.set_pointer_offsets_length(pointer_offsets_length); | 10002 result.set_pointer_offsets_length(pointer_offsets_length); |
10003 result.set_is_optimized(false); | 10003 result.set_is_optimized(false); |
10004 result.set_is_alive(true); | 10004 result.set_is_alive(false); |
10005 result.set_comments(Comments::New(0)); | 10005 result.set_comments(Comments::New(0)); |
10006 result.set_pc_descriptors(Object::empty_descriptors()); | 10006 result.set_pc_descriptors(Object::empty_descriptors()); |
10007 } | 10007 } |
10008 return result.raw(); | 10008 return result.raw(); |
10009 } | 10009 } |
10010 | 10010 |
10011 | 10011 |
10012 RawCode* Code::FinalizeCode(const char* name, | 10012 RawCode* Code::FinalizeCode(const char* name, |
10013 Assembler* assembler, | 10013 Assembler* assembler, |
10014 bool optimized) { | 10014 bool optimized) { |
10015 ASSERT(assembler != NULL); | 10015 ASSERT(assembler != NULL); |
10016 | 10016 |
10017 // Allocate the Instructions object. | 10017 // Allocate the Code and Instructions objects. Code is allocated first |
| 10018 // because a GC during allocation of the code will leave the instruction |
| 10019 // pages read-only. |
| 10020 intptr_t pointer_offset_count = assembler->CountPointerOffsets(); |
| 10021 Code& code = Code::ZoneHandle(Code::New(pointer_offset_count)); |
10018 Instructions& instrs = | 10022 Instructions& instrs = |
10019 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); | 10023 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); |
10020 | 10024 |
10021 // Copy the instructions into the instruction area and apply all fixups. | 10025 // Copy the instructions into the instruction area and apply all fixups. |
10022 // Embedded pointers are still in handles at this point. | 10026 // Embedded pointers are still in handles at this point. |
10023 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), | 10027 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), |
10024 instrs.size()); | 10028 instrs.size()); |
10025 assembler->FinalizeInstructions(region); | 10029 assembler->FinalizeInstructions(region); |
10026 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); | 10030 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); |
10027 | 10031 |
10028 CodeObservers::NotifyAll(name, | 10032 CodeObservers::NotifyAll(name, |
10029 instrs.EntryPoint(), | 10033 instrs.EntryPoint(), |
10030 assembler->prologue_offset(), | 10034 assembler->prologue_offset(), |
10031 instrs.size(), | 10035 instrs.size(), |
10032 optimized); | 10036 optimized); |
10033 | 10037 |
10034 const ZoneGrowableArray<intptr_t>& pointer_offsets = | |
10035 assembler->GetPointerOffsets(); | |
10036 | |
10037 // Allocate the code object. | |
10038 Code& code = Code::ZoneHandle(Code::New(pointer_offsets.length())); | |
10039 { | 10038 { |
10040 NoGCScope no_gc; | 10039 NoGCScope no_gc; |
| 10040 const ZoneGrowableArray<intptr_t>& pointer_offsets = |
| 10041 assembler->GetPointerOffsets(); |
| 10042 ASSERT(pointer_offsets.length() == pointer_offset_count); |
| 10043 ASSERT(code.pointer_offsets_length() == pointer_offsets.length()); |
10041 | 10044 |
10042 // Set pointer offsets list in Code object and resolve all handles in | 10045 // Set pointer offsets list in Code object and resolve all handles in |
10043 // the instruction stream to raw objects. | 10046 // the instruction stream to raw objects. |
10044 ASSERT(code.pointer_offsets_length() == pointer_offsets.length()); | |
10045 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { | 10047 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { |
10046 intptr_t offset_in_instrs = pointer_offsets[i]; | 10048 intptr_t offset_in_instrs = pointer_offsets[i]; |
10047 code.SetPointerOffsetAt(i, offset_in_instrs); | 10049 code.SetPointerOffsetAt(i, offset_in_instrs); |
10048 const Object* object = region.Load<const Object*>(offset_in_instrs); | 10050 const Object* object = region.Load<const Object*>(offset_in_instrs); |
10049 region.Store<RawObject*>(offset_in_instrs, object->raw()); | 10051 region.Store<RawObject*>(offset_in_instrs, object->raw()); |
10050 } | 10052 } |
10051 | 10053 |
10052 // Hook up Code and Instructions objects. | 10054 // Hook up Code and Instructions objects. |
10053 instrs.set_code(code.raw()); | 10055 instrs.set_code(code.raw()); |
10054 code.set_instructions(instrs.raw()); | 10056 code.set_instructions(instrs.raw()); |
| 10057 code.set_is_alive(true); |
10055 | 10058 |
10056 // Set object pool in Instructions object. | 10059 // Set object pool in Instructions object. |
10057 const GrowableObjectArray& object_pool = assembler->object_pool(); | 10060 const GrowableObjectArray& object_pool = assembler->object_pool(); |
10058 if (object_pool.IsNull()) { | 10061 if (object_pool.IsNull()) { |
10059 instrs.set_object_pool(Object::empty_array().raw()); | 10062 instrs.set_object_pool(Object::empty_array().raw()); |
10060 } else { | 10063 } else { |
10061 // TODO(regis): Once MakeArray takes a Heap::Space argument, call it here | 10064 // TODO(regis): Once MakeArray takes a Heap::Space argument, call it here |
10062 // with Heap::kOld and change the ARM and MIPS assemblers to work with a | 10065 // with Heap::kOld and change the ARM and MIPS assemblers to work with a |
10063 // GrowableObjectArray in new space. | 10066 // GrowableObjectArray in new space. |
10064 instrs.set_object_pool(Array::MakeArray(object_pool)); | 10067 instrs.set_object_pool(Array::MakeArray(object_pool)); |
10065 } | 10068 } |
| 10069 bool status = |
| 10070 VirtualMemory::Protect(reinterpret_cast<void*>(instrs.raw_ptr()), |
| 10071 instrs.raw()->Size(), |
| 10072 VirtualMemory::kReadExecute); |
| 10073 ASSERT(status); |
10066 } | 10074 } |
10067 return code.raw(); | 10075 return code.raw(); |
10068 } | 10076 } |
10069 | 10077 |
10070 | 10078 |
10071 RawCode* Code::FinalizeCode(const Function& function, | 10079 RawCode* Code::FinalizeCode(const Function& function, |
10072 Assembler* assembler, | 10080 Assembler* assembler, |
10073 bool optimized) { | 10081 bool optimized) { |
10074 // Calling ToFullyQualifiedCString is very expensive, try to avoid it. | 10082 // Calling ToFullyQualifiedCString is very expensive, try to avoid it. |
10075 if (CodeObservers::AreActive()) { | 10083 if (CodeObservers::AreActive()) { |
(...skipping 7022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17098 return "_MirrorReference"; | 17106 return "_MirrorReference"; |
17099 } | 17107 } |
17100 | 17108 |
17101 | 17109 |
17102 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 17110 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
17103 Instance::PrintToJSONStream(stream, ref); | 17111 Instance::PrintToJSONStream(stream, ref); |
17104 } | 17112 } |
17105 | 17113 |
17106 | 17114 |
17107 } // namespace dart | 17115 } // namespace dart |
OLD | NEW |