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

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

Issue 315583002: First step in reducing the size of PC descriptors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments, added arm64 file. Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/flow_graph_builder.cc » ('j') | runtime/vm/raw_object.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/code_patcher.h" 5 #include "vm/code_patcher.h"
6 #include "vm/cpu.h" 6 #include "vm/cpu.h"
7 #include "vm/instructions.h" 7 #include "vm/instructions.h"
8 #include "vm/object.h" 8 #include "vm/object.h"
9 #include "vm/virtual_memory.h" 9 #include "vm/virtual_memory.h"
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 buffer++; 45 buffer++;
46 } 46 }
47 CPU::FlushICache(code_address, num_bytes); 47 CPU::FlushICache(code_address, num_bytes);
48 // The buffer is not executed. No need to flush. 48 // The buffer is not executed. No need to flush.
49 } 49 }
50 50
51 51
52 // The patch code buffer contains the jmp code which will be inserted at 52 // The patch code buffer contains the jmp code which will be inserted at
53 // entry point. 53 // entry point.
54 void CodePatcher::PatchEntry(const Code& code) { 54 void CodePatcher::PatchEntry(const Code& code) {
55 const uword patch_addr = code.GetPcForDeoptId(Isolate::kNoDeoptId, 55 const uword patch_addr = code.GetEntryPatchPc();
56 PcDescriptors::kEntryPatch);
57 ASSERT(patch_addr != 0); 56 ASSERT(patch_addr != 0);
58 JumpPattern jmp_entry(patch_addr, code); 57 JumpPattern jmp_entry(patch_addr, code);
59 ASSERT(!jmp_entry.IsValid()); 58 ASSERT(!jmp_entry.IsValid());
60 const uword patch_buffer = code.GetPatchCodePc(); 59 const uword patch_buffer = code.GetPatchCodePc();
61 ASSERT(patch_buffer != 0); 60 ASSERT(patch_buffer != 0);
62 JumpPattern jmp_patch(patch_buffer, code); 61 JumpPattern jmp_patch(patch_buffer, code);
63 ASSERT(jmp_patch.IsValid()); 62 ASSERT(jmp_patch.IsValid());
64 const uword jump_target = jmp_patch.TargetAddress(); 63 const uword jump_target = jmp_patch.TargetAddress();
65 intptr_t length = jmp_patch.pattern_length_in_bytes(); 64 intptr_t length = jmp_patch.pattern_length_in_bytes();
66 { 65 {
67 WritableInstructionsScope writable_code(patch_addr, length); 66 WritableInstructionsScope writable_code(patch_addr, length);
68 WritableInstructionsScope writable_buffer(patch_buffer, length); 67 WritableInstructionsScope writable_buffer(patch_buffer, length);
69 SwapCode(jmp_patch.pattern_length_in_bytes(), 68 SwapCode(jmp_patch.pattern_length_in_bytes(),
70 reinterpret_cast<char*>(patch_addr), 69 reinterpret_cast<char*>(patch_addr),
71 reinterpret_cast<char*>(patch_buffer)); 70 reinterpret_cast<char*>(patch_buffer));
72 jmp_entry.SetTargetAddress(jump_target); 71 jmp_entry.SetTargetAddress(jump_target);
73 } 72 }
74 } 73 }
75 74
76 75
77 // The entry point is a jmp instruction, the patch code buffer contains 76 // The entry point is a jmp instruction, the patch code buffer contains
78 // original code, the entry point contains the jump instruction. 77 // original code, the entry point contains the jump instruction.
79 void CodePatcher::RestoreEntry(const Code& code) { 78 void CodePatcher::RestoreEntry(const Code& code) {
80 const uword patch_addr = code.GetPcForDeoptId(Isolate::kNoDeoptId, 79 const uword patch_addr = code.GetEntryPatchPc();
81 PcDescriptors::kEntryPatch);
82 ASSERT(patch_addr != 0); 80 ASSERT(patch_addr != 0);
83 JumpPattern jmp_entry(patch_addr, code); 81 JumpPattern jmp_entry(patch_addr, code);
84 ASSERT(jmp_entry.IsValid()); 82 ASSERT(jmp_entry.IsValid());
85 const uword jump_target = jmp_entry.TargetAddress(); 83 const uword jump_target = jmp_entry.TargetAddress();
86 const uword patch_buffer = code.GetPatchCodePc(); 84 const uword patch_buffer = code.GetPatchCodePc();
87 ASSERT(patch_buffer != 0); 85 ASSERT(patch_buffer != 0);
88 // 'patch_buffer' contains original entry code. 86 // 'patch_buffer' contains original entry code.
89 JumpPattern jmp_patch(patch_buffer, code); 87 JumpPattern jmp_patch(patch_buffer, code);
90 ASSERT(!jmp_patch.IsValid()); 88 ASSERT(!jmp_patch.IsValid());
91 intptr_t length = jmp_patch.pattern_length_in_bytes(); 89 intptr_t length = jmp_patch.pattern_length_in_bytes();
92 { 90 {
93 WritableInstructionsScope writable_code(patch_addr, length); 91 WritableInstructionsScope writable_code(patch_addr, length);
94 WritableInstructionsScope writable_buffer(patch_buffer, length); 92 WritableInstructionsScope writable_buffer(patch_buffer, length);
95 SwapCode(jmp_patch.pattern_length_in_bytes(), 93 SwapCode(jmp_patch.pattern_length_in_bytes(),
96 reinterpret_cast<char*>(patch_addr), 94 reinterpret_cast<char*>(patch_addr),
97 reinterpret_cast<char*>(patch_buffer)); 95 reinterpret_cast<char*>(patch_buffer));
98 ASSERT(jmp_patch.IsValid()); 96 ASSERT(jmp_patch.IsValid());
99 jmp_patch.SetTargetAddress(jump_target); 97 jmp_patch.SetTargetAddress(jump_target);
100 } 98 }
101 } 99 }
102 100
103 101
104 bool CodePatcher::IsEntryPatched(const Code& code) { 102 bool CodePatcher::IsEntryPatched(const Code& code) {
105 const uword patch_addr = code.GetPcForDeoptId(Isolate::kNoDeoptId, 103 const uword patch_addr = code.GetEntryPatchPc();
106 PcDescriptors::kEntryPatch);
107 if (patch_addr == 0) { 104 if (patch_addr == 0) {
108 return false; 105 return false;
109 } 106 }
110 JumpPattern jmp_entry(patch_addr, code); 107 JumpPattern jmp_entry(patch_addr, code);
111 return jmp_entry.IsValid(); 108 return jmp_entry.IsValid();
112 } 109 }
113 110
114 111
115 bool CodePatcher::CodeIsPatchable(const Code& code) { 112 bool CodePatcher::CodeIsPatchable(const Code& code) {
116 const uword patch_addr = code.GetPcForDeoptId(Isolate::kNoDeoptId, 113 const uword patch_addr = code.GetEntryPatchPc();
117 PcDescriptors::kEntryPatch); 114 // Zero means means that the function is not patchable.
118 // kEntryPatch may not exist which means the function is not patchable.
119 if (patch_addr == 0) { 115 if (patch_addr == 0) {
120 return false; 116 return false;
121 } 117 }
122 JumpPattern jmp_entry(patch_addr, code); 118 JumpPattern jmp_entry(patch_addr, code);
123 if (code.Size() < (jmp_entry.pattern_length_in_bytes() * 2)) { 119 if (code.Size() < (jmp_entry.pattern_length_in_bytes() * 2)) {
124 return false; 120 return false;
125 } 121 }
126 const uword limit = patch_addr + jmp_entry.pattern_length_in_bytes(); 122 const uword limit = patch_addr + jmp_entry.pattern_length_in_bytes();
127 // Check no object stored between patch_addr .. limit. 123 // Check no object stored between patch_addr .. limit.
128 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) { 124 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) {
129 const uword obj_start = code.GetPointerOffsetAt(i) + code.EntryPoint(); 125 const uword obj_start = code.GetPointerOffsetAt(i) + code.EntryPoint();
130 const uword obj_end = obj_start + kWordSize; 126 const uword obj_end = obj_start + kWordSize;
131 if ((obj_start < limit) && (obj_end > patch_addr)) { 127 if ((obj_start < limit) && (obj_end > patch_addr)) {
132 return false; 128 return false;
133 } 129 }
134 } 130 }
135 return true; 131 return true;
136 } 132 }
137 133
138 } // namespace dart 134 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_builder.cc » ('j') | runtime/vm/raw_object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698