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 9543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9554 } | 9554 } |
9555 ASSERT(Object::code_class() != Class::null()); | 9555 ASSERT(Object::code_class() != Class::null()); |
9556 Code& result = Code::Handle(); | 9556 Code& result = Code::Handle(); |
9557 { | 9557 { |
9558 uword size = Code::InstanceSize(pointer_offsets_length); | 9558 uword size = Code::InstanceSize(pointer_offsets_length); |
9559 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); | 9559 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); |
9560 NoGCScope no_gc; | 9560 NoGCScope no_gc; |
9561 result ^= raw; | 9561 result ^= raw; |
9562 result.set_pointer_offsets_length(pointer_offsets_length); | 9562 result.set_pointer_offsets_length(pointer_offsets_length); |
9563 result.set_is_optimized(false); | 9563 result.set_is_optimized(false); |
9564 result.set_is_alive(true); | 9564 result.set_is_alive(false); |
9565 result.set_comments(Comments::New(0)); | 9565 result.set_comments(Comments::New(0)); |
9566 } | 9566 } |
9567 return result.raw(); | 9567 return result.raw(); |
9568 } | 9568 } |
9569 | 9569 |
9570 | 9570 |
9571 RawCode* Code::FinalizeCode(const char* name, | 9571 RawCode* Code::FinalizeCode(const char* name, |
9572 Assembler* assembler, | 9572 Assembler* assembler, |
9573 bool optimized) { | 9573 bool optimized) { |
9574 ASSERT(assembler != NULL); | 9574 ASSERT(assembler != NULL); |
9575 | 9575 |
9576 // Allocate the Instructions object. | 9576 // Allocate the Code and Instructions objects. Code is allocated first |
| 9577 // because a GC during allocation of the code will leave the instruction |
| 9578 // pages read-only. |
| 9579 intptr_t pointer_offset_count = assembler->CountPointerOffsets(); |
| 9580 Code& code = Code::ZoneHandle(Code::New(pointer_offset_count)); |
9577 Instructions& instrs = | 9581 Instructions& instrs = |
9578 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); | 9582 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); |
9579 | 9583 |
9580 // Copy the instructions into the instruction area and apply all fixups. | 9584 // Copy the instructions into the instruction area and apply all fixups. |
9581 // Embedded pointers are still in handles at this point. | 9585 // Embedded pointers are still in handles at this point. |
9582 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), | 9586 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), |
9583 instrs.size()); | 9587 instrs.size()); |
9584 assembler->FinalizeInstructions(region); | 9588 assembler->FinalizeInstructions(region); |
9585 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); | 9589 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); |
9586 | 9590 |
9587 CodeObservers::NotifyAll(name, | 9591 CodeObservers::NotifyAll(name, |
9588 instrs.EntryPoint(), | 9592 instrs.EntryPoint(), |
9589 assembler->prologue_offset(), | 9593 assembler->prologue_offset(), |
9590 instrs.size(), | 9594 instrs.size(), |
9591 optimized); | 9595 optimized); |
9592 | 9596 |
9593 const ZoneGrowableArray<intptr_t>& pointer_offsets = | |
9594 assembler->GetPointerOffsets(); | |
9595 | |
9596 // Allocate the code object. | |
9597 Code& code = Code::ZoneHandle(Code::New(pointer_offsets.length())); | |
9598 { | 9597 { |
9599 NoGCScope no_gc; | 9598 NoGCScope no_gc; |
| 9599 const ZoneGrowableArray<intptr_t>& pointer_offsets = |
| 9600 assembler->GetPointerOffsets(); |
| 9601 ASSERT(pointer_offsets.length() == pointer_offset_count); |
| 9602 ASSERT(code.pointer_offsets_length() == pointer_offsets.length()); |
9600 | 9603 |
9601 // Set pointer offsets list in Code object and resolve all handles in | 9604 // Set pointer offsets list in Code object and resolve all handles in |
9602 // the instruction stream to raw objects. | 9605 // the instruction stream to raw objects. |
9603 ASSERT(code.pointer_offsets_length() == pointer_offsets.length()); | |
9604 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { | 9606 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { |
9605 intptr_t offset_in_instrs = pointer_offsets[i]; | 9607 intptr_t offset_in_instrs = pointer_offsets[i]; |
9606 code.SetPointerOffsetAt(i, offset_in_instrs); | 9608 code.SetPointerOffsetAt(i, offset_in_instrs); |
9607 const Object* object = region.Load<const Object*>(offset_in_instrs); | 9609 const Object* object = region.Load<const Object*>(offset_in_instrs); |
9608 region.Store<RawObject*>(offset_in_instrs, object->raw()); | 9610 region.Store<RawObject*>(offset_in_instrs, object->raw()); |
9609 } | 9611 } |
9610 | 9612 |
9611 // Hook up Code and Instructions objects. | 9613 // Hook up Code and Instructions objects. |
9612 instrs.set_code(code.raw()); | 9614 instrs.set_code(code.raw()); |
9613 code.set_instructions(instrs.raw()); | 9615 code.set_instructions(instrs.raw()); |
| 9616 code.set_is_alive(true); |
9614 | 9617 |
9615 // Set object pool in Instructions object. | 9618 // Set object pool in Instructions object. |
9616 const GrowableObjectArray& object_pool = assembler->object_pool(); | 9619 const GrowableObjectArray& object_pool = assembler->object_pool(); |
9617 if (object_pool.IsNull()) { | 9620 if (object_pool.IsNull()) { |
9618 instrs.set_object_pool(Object::empty_array().raw()); | 9621 instrs.set_object_pool(Object::empty_array().raw()); |
9619 } else { | 9622 } else { |
9620 // TODO(regis): Once MakeArray takes a Heap::Space argument, call it here | 9623 // TODO(regis): Once MakeArray takes a Heap::Space argument, call it here |
9621 // with Heap::kOld and change the ARM and MIPS assemblers to work with a | 9624 // with Heap::kOld and change the ARM and MIPS assemblers to work with a |
9622 // GrowableObjectArray in new space. | 9625 // GrowableObjectArray in new space. |
9623 instrs.set_object_pool(Array::MakeArray(object_pool)); | 9626 instrs.set_object_pool(Array::MakeArray(object_pool)); |
9624 } | 9627 } |
| 9628 bool status = |
| 9629 VirtualMemory::Protect(reinterpret_cast<void*>(instrs.raw_ptr()), |
| 9630 instrs.raw()->Size(), |
| 9631 VirtualMemory::kReadExecute); |
| 9632 ASSERT(status); |
9625 } | 9633 } |
9626 return code.raw(); | 9634 return code.raw(); |
9627 } | 9635 } |
9628 | 9636 |
9629 | 9637 |
9630 RawCode* Code::FinalizeCode(const Function& function, | 9638 RawCode* Code::FinalizeCode(const Function& function, |
9631 Assembler* assembler, | 9639 Assembler* assembler, |
9632 bool optimized) { | 9640 bool optimized) { |
9633 // Calling ToFullyQualifiedCString is very expensive, try to avoid it. | 9641 // Calling ToFullyQualifiedCString is very expensive, try to avoid it. |
9634 if (CodeObservers::AreActive()) { | 9642 if (CodeObservers::AreActive()) { |
(...skipping 6420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16055 return "_MirrorReference"; | 16063 return "_MirrorReference"; |
16056 } | 16064 } |
16057 | 16065 |
16058 | 16066 |
16059 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 16067 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
16060 Instance::PrintToJSONStream(stream, ref); | 16068 Instance::PrintToJSONStream(stream, ref); |
16061 } | 16069 } |
16062 | 16070 |
16063 | 16071 |
16064 } // namespace dart | 16072 } // namespace dart |
OLD | NEW |