Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: runtime/vm/object.cc

Issue 1192103004: VM: New calling convention for generated code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: ARM64 port Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 3689 matching lines...) Expand 10 before | Expand all | Expand 10 after
3700 } 3700 }
3701 3701
3702 3702
3703 void Class::DisableAllocationStub() const { 3703 void Class::DisableAllocationStub() const {
3704 const Code& existing_stub = Code::Handle(allocation_stub()); 3704 const Code& existing_stub = Code::Handle(allocation_stub());
3705 if (existing_stub.IsNull()) { 3705 if (existing_stub.IsNull()) {
3706 return; 3706 return;
3707 } 3707 }
3708 ASSERT(!CodePatcher::IsEntryPatched(existing_stub)); 3708 ASSERT(!CodePatcher::IsEntryPatched(existing_stub));
3709 // Patch the stub so that the next caller will regenerate the stub. 3709 // Patch the stub so that the next caller will regenerate the stub.
3710 CodePatcher::PatchEntry(existing_stub); 3710 CodePatcher::PatchEntry(
3711 existing_stub,
3712 Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()));
3711 // Disassociate the existing stub from class. 3713 // Disassociate the existing stub from class.
3712 StorePointer(&raw_ptr()->allocation_stub_, Code::null()); 3714 StorePointer(&raw_ptr()->allocation_stub_, Code::null());
3713 } 3715 }
3714 3716
3715 3717
3716 bool Class::IsFunctionClass() const { 3718 bool Class::IsFunctionClass() const {
3717 return raw() == Type::Handle(Type::Function()).type_class(); 3719 return raw() == Type::Handle(Type::Function()).type_class();
3718 } 3720 }
3719 3721
3720 3722
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
5221 StorePointer(&raw_ptr()->source_class_, value.raw()); 5223 StorePointer(&raw_ptr()->source_class_, value.raw());
5222 } 5224 }
5223 5225
5224 5226
5225 bool Function::HasBreakpoint() const { 5227 bool Function::HasBreakpoint() const {
5226 return Isolate::Current()->debugger()->HasBreakpoint(*this); 5228 return Isolate::Current()->debugger()->HasBreakpoint(*this);
5227 } 5229 }
5228 5230
5229 5231
5230 void Function::SetInstructions(const Code& value) const { 5232 void Function::SetInstructions(const Code& value) const {
5231 StorePointer(&raw_ptr()->instructions_, value.instructions()); 5233 StorePointer(&raw_ptr()->code_, value.raw());
5232 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint()); 5234 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint());
5233 } 5235 }
5234 5236
5235 void Function::AttachCode(const Code& value) const { 5237 void Function::AttachCode(const Code& value) const {
5236 SetInstructions(value); 5238 SetInstructions(value);
5237 ASSERT(Function::Handle(value.function()).IsNull() || 5239 ASSERT(Function::Handle(value.function()).IsNull() ||
5238 (value.function() == this->raw())); 5240 (value.function() == this->raw()));
5239 value.set_owner(*this); 5241 value.set_owner(*this);
5240 } 5242 }
5241 5243
5242 5244
5243 bool Function::HasCode() const { 5245 bool Function::HasCode() const {
5244 ASSERT(raw_ptr()->instructions_ != Instructions::null()); 5246 ASSERT(raw_ptr()->code_ != Code::null());
5245 return raw_ptr()->instructions_ != 5247 return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code();
5246 StubCode::LazyCompile_entry()->code()->ptr()->instructions_;
5247 } 5248 }
5248 5249
5249 5250
5250 void Function::ClearCode() const { 5251 void Function::ClearCode() const {
5251 ASSERT(ic_data_array() == Array::null()); 5252 ASSERT(ic_data_array() == Array::null());
5252 StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); 5253 StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
5253 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); 5254 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
5254 } 5255 }
5255 5256
5256 5257
5257 void Function::SwitchToUnoptimizedCode() const { 5258 void Function::SwitchToUnoptimizedCode() const {
5258 ASSERT(HasOptimizedCode()); 5259 ASSERT(HasOptimizedCode());
5259 Thread* thread = Thread::Current(); 5260 Thread* thread = Thread::Current();
5260 Isolate* isolate = thread->isolate(); 5261 Isolate* isolate = thread->isolate();
5261 Zone* zone = thread->zone(); 5262 Zone* zone = thread->zone();
5262 const Code& current_code = Code::Handle(zone, CurrentCode()); 5263 const Code& current_code = Code::Handle(zone, CurrentCode());
5263 5264
5264 if (FLAG_trace_deoptimization_verbose) { 5265 if (FLAG_trace_deoptimization_verbose) {
5265 ISL_Print("Disabling optimized code: '%s' entry: %#" Px "\n", 5266 ISL_Print("Disabling optimized code: '%s' entry: %#" Px "\n",
5266 ToFullyQualifiedCString(), 5267 ToFullyQualifiedCString(),
5267 current_code.EntryPoint()); 5268 current_code.EntryPoint());
5268 } 5269 }
5269 // Patch entry of the optimized code. 5270 // Patch entry of the optimized code.
5270 CodePatcher::PatchEntry(current_code); 5271 CodePatcher::PatchEntry(
5272 current_code, Code::Handle(StubCode::FixCallersTarget_entry()->code()));
5271 const Error& error = Error::Handle(zone, 5273 const Error& error = Error::Handle(zone,
5272 Compiler::EnsureUnoptimizedCode(thread, *this)); 5274 Compiler::EnsureUnoptimizedCode(thread, *this));
5273 if (!error.IsNull()) { 5275 if (!error.IsNull()) {
5274 Exceptions::PropagateError(error); 5276 Exceptions::PropagateError(error);
5275 } 5277 }
5276 const Code& unopt_code = Code::Handle(zone, unoptimized_code()); 5278 const Code& unopt_code = Code::Handle(zone, unoptimized_code());
5277 AttachCode(unopt_code); 5279 AttachCode(unopt_code);
5278 CodePatcher::RestoreEntry(unopt_code); 5280 CodePatcher::RestoreEntry(unopt_code);
5279 isolate->TrackDeoptimizedCode(current_code); 5281 isolate->TrackDeoptimizedCode(current_code);
5280 } 5282 }
(...skipping 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after
6716 const Object& obj = Object::Handle(raw_ptr()->owner_); 6718 const Object& obj = Object::Handle(raw_ptr()->owner_);
6717 if (obj.IsClass()) { 6719 if (obj.IsClass()) {
6718 return Class::Cast(obj).script(); 6720 return Class::Cast(obj).script();
6719 } 6721 }
6720 ASSERT(obj.IsPatchClass()); 6722 ASSERT(obj.IsPatchClass());
6721 return PatchClass::Cast(obj).Script(); 6723 return PatchClass::Cast(obj).Script();
6722 } 6724 }
6723 6725
6724 6726
6725 bool Function::HasOptimizedCode() const { 6727 bool Function::HasOptimizedCode() const {
6726 return HasCode() && Code::Handle(Instructions::Handle( 6728 return HasCode() && Code::Handle(CurrentCode()).is_optimized();
6727 raw_ptr()->instructions_).code()).is_optimized();
6728 } 6729 }
6729 6730
6730 6731
6731 RawString* Function::PrettyName() const { 6732 RawString* Function::PrettyName() const {
6732 const String& str = String::Handle(name()); 6733 const String& str = String::Handle(name());
6733 return String::IdentifierPrettyName(str); 6734 return String::IdentifierPrettyName(str);
6734 } 6735 }
6735 6736
6736 6737
6737 const char* Function::QualifiedUserVisibleNameCString() const { 6738 const char* Function::QualifiedUserVisibleNameCString() const {
(...skipping 4172 matching lines...) Expand 10 before | Expand all | Expand 10 after
10910 10911
10911 const char* Instructions::ToCString() const { 10912 const char* Instructions::ToCString() const {
10912 return "Instructions"; 10913 return "Instructions";
10913 } 10914 }
10914 10915
10915 10916
10916 void Instructions::PrintJSONImpl(JSONStream* stream, bool ref) const { 10917 void Instructions::PrintJSONImpl(JSONStream* stream, bool ref) const {
10917 JSONObject jsobj(stream); 10918 JSONObject jsobj(stream);
10918 AddCommonObjectProperties(&jsobj, "Object", ref); 10919 AddCommonObjectProperties(&jsobj, "Object", ref);
10919 jsobj.AddServiceId(*this); 10920 jsobj.AddServiceId(*this);
10920 jsobj.AddProperty("_code", Code::Handle(code()));
10921 if (ref) { 10921 if (ref) {
10922 return; 10922 return;
10923 } 10923 }
10924 jsobj.AddProperty("_objectPool", ObjectPool::Handle(object_pool()));
10925 } 10924 }
10926 10925
10927 10926
10928 // Encode integer in SLEB128 format. 10927 // Encode integer in SLEB128 format.
10929 void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data, 10928 void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data,
10930 intptr_t value) { 10929 intptr_t value) {
10931 bool is_last_part = false; 10930 bool is_last_part = false;
10932 while (!is_last_part) { 10931 while (!is_last_part) {
10933 intptr_t part = value & 0x7f; 10932 intptr_t part = value & 0x7f;
10934 value >>= 7; 10933 value >>= 7;
(...skipping 1919 matching lines...) Expand 10 before | Expand all | Expand 10 after
12854 } else { 12853 } else {
12855 ASSERT(code.IsNull() || 12854 ASSERT(code.IsNull() ||
12856 (code.function() == array.At(i + kSCallTableFunctionEntry))); 12855 (code.function() == array.At(i + kSCallTableFunctionEntry)));
12857 } 12856 }
12858 #endif 12857 #endif
12859 array.SetAt(i + kSCallTableCodeEntry, code); 12858 array.SetAt(i + kSCallTableCodeEntry, code);
12860 } 12859 }
12861 12860
12862 12861
12863 void Code::Disassemble(DisassemblyFormatter* formatter) const { 12862 void Code::Disassemble(DisassemblyFormatter* formatter) const {
12864 const bool fix_patch = CodePatcher::CodeIsPatchable(*this) &&
12865 CodePatcher::IsEntryPatched(*this);
12866 if (fix_patch) {
12867 // The disassembler may choke on illegal instructions if the code has been
12868 // patched, un-patch the code before disassembling and re-patch after.
12869 CodePatcher::RestoreEntry(*this);
12870 }
12871 const Instructions& instr = Instructions::Handle(instructions()); 12863 const Instructions& instr = Instructions::Handle(instructions());
12872 uword start = instr.EntryPoint(); 12864 uword start = instr.EntryPoint();
12873 if (formatter == NULL) { 12865 if (formatter == NULL) {
12874 Disassembler::Disassemble(start, start + instr.size(), *this); 12866 Disassembler::Disassemble(start, start + instr.size(), *this);
12875 } else { 12867 } else {
12876 Disassembler::Disassemble(start, start + instr.size(), formatter, *this); 12868 Disassembler::Disassemble(start, start + instr.size(), formatter, *this);
12877 } 12869 }
12878 if (fix_patch) {
12879 // Redo the patch.
12880 CodePatcher::PatchEntry(*this);
12881 }
12882 } 12870 }
12883 12871
12884 12872
12885 const Code::Comments& Code::comments() const { 12873 const Code::Comments& Code::comments() const {
12886 Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_)); 12874 Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_));
12887 return *comments; 12875 return *comments;
12888 } 12876 }
12889 12877
12890 12878
12891 void Code::set_comments(const Code::Comments& comments) const { 12879 void Code::set_comments(const Code::Comments& comments) const {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
12993 { 12981 {
12994 uword size = Code::InstanceSize(pointer_offsets_length); 12982 uword size = Code::InstanceSize(pointer_offsets_length);
12995 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); 12983 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
12996 NoSafepointScope no_safepoint; 12984 NoSafepointScope no_safepoint;
12997 result ^= raw; 12985 result ^= raw;
12998 result.set_pointer_offsets_length(pointer_offsets_length); 12986 result.set_pointer_offsets_length(pointer_offsets_length);
12999 result.set_is_optimized(false); 12987 result.set_is_optimized(false);
13000 result.set_is_alive(false); 12988 result.set_is_alive(false);
13001 result.set_comments(Comments::New(0)); 12989 result.set_comments(Comments::New(0));
13002 result.set_compile_timestamp(0); 12990 result.set_compile_timestamp(0);
13003 result.set_entry_patch_pc_offset(kInvalidPc);
13004 result.set_patch_code_pc_offset(kInvalidPc);
13005 result.set_lazy_deopt_pc_offset(kInvalidPc); 12991 result.set_lazy_deopt_pc_offset(kInvalidPc);
13006 result.set_pc_descriptors(Object::empty_descriptors()); 12992 result.set_pc_descriptors(Object::empty_descriptors());
13007 } 12993 }
13008 return result.raw(); 12994 return result.raw();
13009 } 12995 }
13010 12996
13011 12997
13012 RawCode* Code::FinalizeCode(const char* name, 12998 RawCode* Code::FinalizeCode(const char* name,
13013 Assembler* assembler, 12999 Assembler* assembler,
13014 bool optimized) { 13000 bool optimized) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
13057 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { 13043 for (intptr_t i = 0; i < pointer_offsets.length(); i++) {
13058 intptr_t offset_in_instrs = pointer_offsets[i]; 13044 intptr_t offset_in_instrs = pointer_offsets[i];
13059 code.SetPointerOffsetAt(i, offset_in_instrs); 13045 code.SetPointerOffsetAt(i, offset_in_instrs);
13060 uword addr = region.start() + offset_in_instrs; 13046 uword addr = region.start() + offset_in_instrs;
13061 const Object* object = *reinterpret_cast<Object**>(addr); 13047 const Object* object = *reinterpret_cast<Object**>(addr);
13062 instrs.raw()->StorePointer(reinterpret_cast<RawObject**>(addr), 13048 instrs.raw()->StorePointer(reinterpret_cast<RawObject**>(addr),
13063 object->raw()); 13049 object->raw());
13064 } 13050 }
13065 13051
13066 // Hook up Code and Instructions objects. 13052 // Hook up Code and Instructions objects.
13067 instrs.set_code(code.raw()); 13053 code.set_active_instructions(instrs.raw());
13068 code.set_instructions(instrs.raw()); 13054 code.set_instructions(instrs.raw());
13069 code.set_is_alive(true); 13055 code.set_is_alive(true);
13070 13056
13071 // Set object pool in Instructions object. 13057 // Set object pool in Instructions object.
13072 INC_STAT(Thread::Current(), 13058 INC_STAT(Thread::Current(),
13073 total_code_size, object_pool.Length() * sizeof(uintptr_t)); 13059 total_code_size, object_pool.Length() * sizeof(uintptr_t));
13074 instrs.set_object_pool(object_pool.raw()); 13060 code.set_object_pool(object_pool.raw());
13075 13061
13076 if (FLAG_write_protect_code) { 13062 if (FLAG_write_protect_code) {
13077 uword address = RawObject::ToAddr(instrs.raw()); 13063 uword address = RawObject::ToAddr(instrs.raw());
13078 bool status = VirtualMemory::Protect( 13064 bool status = VirtualMemory::Protect(
13079 reinterpret_cast<void*>(address), 13065 reinterpret_cast<void*>(address),
13080 instrs.raw()->Size(), 13066 instrs.raw()->Size(),
13081 VirtualMemory::kReadExecute); 13067 VirtualMemory::kReadExecute);
13082 ASSERT(status); 13068 ASSERT(status);
13083 } 13069 }
13084 } 13070 }
(...skipping 21 matching lines...) Expand all
13106 assembler, 13092 assembler,
13107 optimized); 13093 optimized);
13108 } else { 13094 } else {
13109 return FinalizeCode("", assembler); 13095 return FinalizeCode("", assembler);
13110 } 13096 }
13111 } 13097 }
13112 13098
13113 13099
13114 // Check if object matches find condition. 13100 // Check if object matches find condition.
13115 bool Code::FindRawCodeVisitor::FindObject(RawObject* obj) const { 13101 bool Code::FindRawCodeVisitor::FindObject(RawObject* obj) const {
13116 return RawInstructions::ContainsPC(obj, pc_); 13102 return RawCode::ContainsPC(obj, pc_);
13117 } 13103 }
13118 13104
13119 13105
13120 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { 13106 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) {
13121 ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate())); 13107 ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate()));
13122 NoSafepointScope no_safepoint; 13108 NoSafepointScope no_safepoint;
13123 FindRawCodeVisitor visitor(pc); 13109 FindRawCodeVisitor visitor(pc);
13124 RawInstructions* instr; 13110 RawObject* instr;
13125 if (isolate->heap() == NULL) { 13111 if (isolate->heap() == NULL) {
13126 return Code::null(); 13112 return Code::null();
13127 } 13113 }
13128 instr = isolate->heap()->FindObjectInCodeSpace(&visitor); 13114 instr = isolate->heap()->FindOldObject(&visitor);
13129 if (instr != Instructions::null()) { 13115 if (instr != Code::null()) {
13130 return instr->ptr()->code_; 13116 return static_cast<RawCode*>(instr);
13131 } 13117 }
13132 return Code::null(); 13118 return Code::null();
13133 } 13119 }
13134 13120
13135 13121
13136 RawCode* Code::LookupCode(uword pc) { 13122 RawCode* Code::LookupCode(uword pc) {
13137 return LookupCodeInIsolate(Isolate::Current(), pc); 13123 return LookupCodeInIsolate(Isolate::Current(), pc);
13138 } 13124 }
13139 13125
13140 13126
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
13361 while (inlining_id >= 0) { 13347 while (inlining_id >= 0) {
13362 inline_interval.AddValue(inlining_id); 13348 inline_interval.AddValue(inlining_id);
13363 inlining_id = caller_id; 13349 inlining_id = caller_id;
13364 caller_id = GetCallerId(inlining_id); 13350 caller_id = GetCallerId(inlining_id);
13365 } 13351 }
13366 } 13352 }
13367 } 13353 }
13368 } 13354 }
13369 13355
13370 13356
13371 uword Code::GetEntryPatchPc() const {
13372 return (entry_patch_pc_offset() != kInvalidPc)
13373 ? EntryPoint() + entry_patch_pc_offset() : 0;
13374 }
13375
13376
13377 uword Code::GetPatchCodePc() const {
13378 return (patch_code_pc_offset() != kInvalidPc)
13379 ? EntryPoint() + patch_code_pc_offset() : 0;
13380 }
13381
13382
13383 uword Code::GetLazyDeoptPc() const { 13357 uword Code::GetLazyDeoptPc() const {
13384 return (lazy_deopt_pc_offset() != kInvalidPc) 13358 return (lazy_deopt_pc_offset() != kInvalidPc)
13385 ? EntryPoint() + lazy_deopt_pc_offset() : 0; 13359 ? EntryPoint() + lazy_deopt_pc_offset() : 0;
13386 } 13360 }
13387 13361
13388 13362
13389 RawStackmap* Code::GetStackmap( 13363 RawStackmap* Code::GetStackmap(
13390 uint32_t pc_offset, Array* maps, Stackmap* map) const { 13364 uint32_t pc_offset, Array* maps, Stackmap* map) const {
13391 // This code is used during iterating frames during a GC and hence it 13365 // This code is used during iterating frames during a GC and hence it
13392 // should not in turn start a GC. 13366 // should not in turn start a GC.
(...skipping 8128 matching lines...) Expand 10 before | Expand all | Expand 10 after
21521 return tag_label.ToCString(); 21495 return tag_label.ToCString();
21522 } 21496 }
21523 21497
21524 21498
21525 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 21499 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
21526 Instance::PrintJSONImpl(stream, ref); 21500 Instance::PrintJSONImpl(stream, ref);
21527 } 21501 }
21528 21502
21529 21503
21530 } // namespace dart 21504 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | runtime/vm/stack_frame.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698