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

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

Issue 10823131: Add deopt info to code object and print it (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/deopt_instructions.h"
6
7 #include "vm/intermediate_language.h"
8 #include "vm/locations.h"
9 #include "vm/parser.h"
10
11 namespace dart {
12
13 // Deoptimization instruction moving value from optimized frame at
14 // 'from_index' to specified slots in the unoptimized frame.
15 // 'from_index' represents the local count >= 0, first
16 // argument being 0.
17 class DeoptStackSlotInstr : public DeoptInstr {
18 public:
19 explicit DeoptStackSlotInstr(intptr_t from_index)
20 : stack_slot_index_(from_index) {
21 ASSERT(stack_slot_index_ >= 0);
22 }
23
24 virtual intptr_t from_index() const { return stack_slot_index_; }
25 virtual DeoptInstr::Kind kind() const { return kCopyStackSlot; }
26
27 virtual const char* ToCString() const {
28 intptr_t len = OS::SNPrint(NULL, 0, "s%d", stack_slot_index_);
29 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
30 OS::SNPrint(chars, len + 1, "s%d", stack_slot_index_);
31 return chars;
32 }
33
34 private:
35 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
36
37 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr);
38 };
39
40
41 // Deoptimization instruction creating return address using function and
42 // deopt-id stored at 'object_table_index'.
43 class DeoptRetAddrInstr : public DeoptInstr {
44 public:
45 explicit DeoptRetAddrInstr(intptr_t object_table_index)
46 : object_table_index_(object_table_index) {
47 ASSERT(object_table_index >= 0);
48 }
49
50 virtual intptr_t from_index() const { return object_table_index_; }
51 virtual DeoptInstr::Kind kind() const { return kSetRetAddress; }
52
53 virtual const char* ToCString() const {
54 intptr_t len = OS::SNPrint(NULL, 0, "ret oti:%d", object_table_index_);
55 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
56 OS::SNPrint(chars, len + 1, "ret oti:%d", object_table_index_);
57 return chars;
58 }
59
60 private:
61 const intptr_t object_table_index_;
62
63 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrInstr);
64 };
65
66
67 // Deoptimization instruction moving a constant stored at 'object_table_index'.
68 class DeoptConstantInstr : public DeoptInstr {
69 public:
70 explicit DeoptConstantInstr(intptr_t object_table_index)
71 : object_table_index_(object_table_index) {
72 ASSERT(object_table_index >= 0);
73 }
74
75 virtual intptr_t from_index() const { return object_table_index_; }
76 virtual DeoptInstr::Kind kind() const { return kCopyConstant; }
77
78 virtual const char* ToCString() const {
79 intptr_t len = OS::SNPrint(NULL, 0, "const oti:%d", object_table_index_);
80 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
81 OS::SNPrint(chars, len + 1, "const oti:%d", object_table_index_);
82 return chars;
83 }
84
85 private:
86 const intptr_t object_table_index_;
87
88 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr);
89 };
90
91
92 // Deoptimization instruction moving a register.
93 class DeoptRegisterInstr: public DeoptInstr {
94 public:
95 explicit DeoptRegisterInstr(intptr_t reg_as_int)
96 : reg_(static_cast<Register>(reg_as_int)) {}
97
98 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
99 virtual DeoptInstr::Kind kind() const { return kCopyRegister; }
100
101 virtual const char* ToCString() const {
102 return Assembler::RegisterName(reg_);
103 }
104
105 private:
106 const Register reg_;
107
108 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr);
109 };
110
111
112 // Deoptimization instruction creating a PC marker for the code of
113 // function at 'object_table_index'.
114 class DeoptPcMarkerInstr : public DeoptInstr {
115 public:
116 explicit DeoptPcMarkerInstr(intptr_t object_table_index)
117 : object_table_index_(object_table_index) {
118 ASSERT(object_table_index >= 0);
119 }
120
121 virtual intptr_t from_index() const { return object_table_index_; }
122 virtual DeoptInstr::Kind kind() const { return kSetPcMarker; }
123
124 virtual const char* ToCString() const {
125 intptr_t len = OS::SNPrint(NULL, 0, "pcmark oti:%d", object_table_index_);
126 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
127 OS::SNPrint(chars, len + 1, "pcmark oti:%d", object_table_index_);
128 return chars;
129 }
130
131 private:
132 intptr_t object_table_index_;
133
134 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr);
135 };
136
137
138 // Deoptimization instruction copying the caller saved FP from optimized frame.
139 class DeoptCallerFpInstr : public DeoptInstr {
140 public:
141 DeoptCallerFpInstr() {}
142
143 virtual intptr_t from_index() const { return 0; }
144 virtual DeoptInstr::Kind kind() const { return kSetCallerFp; }
145
146 virtual const char* ToCString() const { return "callerfp"; }
147
148 private:
149 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr);
150 };
151
152
153 // Deoptimization instruction copying the caller return address from optimzied
154 // frame.
155 class DeoptCallerPcInstr : public DeoptInstr {
156 public:
157 DeoptCallerPcInstr() {}
158
159 virtual intptr_t from_index() const { return 0; }
160 virtual DeoptInstr::Kind kind() const { return kSetCallerFp; }
161
162 virtual const char* ToCString() const { return "callerpc"; }
163
164 private:
165 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
166 };
167
168
169 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
170 Kind kind = static_cast<Kind>(kind_as_int);
171 switch (kind) {
172 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index);
173 case kSetRetAddress: return new DeoptRetAddrInstr(from_index);
174 case kCopyConstant: return new DeoptConstantInstr(from_index);
175 case kCopyRegister: return new DeoptRegisterInstr(from_index);
176 case kSetPcMarker: return new DeoptPcMarkerInstr(from_index);
177 case kSetCallerFp: return new DeoptCallerFpInstr();
178 case kSetCallerPc: return new DeoptCallerPcInstr();
179 }
180 UNREACHABLE();
181 return NULL;
182 }
183
184
185 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const {
186 for (intptr_t i = 0; i < object_table_.Length(); i++) {
187 if (object_table_.At(i) == obj.raw()) {
188 return i;
189 }
190 }
191 // Add object.
192 const intptr_t result = object_table_.Length();
193 object_table_.Add(obj);
194 return result;
195 }
196
197
198 // Will be neeeded for inlined functions, currently trivial.
199 void DeoptInfoBuilder::AddReturnAddress(const Function& function,
200 intptr_t deopt_id,
201 intptr_t to_index) {
202 const intptr_t object_table_index = object_table_.Length();
203 object_table_.Add(function);
204 object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id)));
205 ASSERT(to_index == instructions_.length());
206 instructions_.Add(new DeoptRetAddrInstr(object_table_index));
207 }
208
209
210 void DeoptInfoBuilder::AddPcMarker(const Function& function,
211 intptr_t to_index) {
212 // Function object was already added by AddReturnAddress, find it.
213 intptr_t from_index = FindOrAddObjectInTable(function);
214 ASSERT(to_index == instructions_.length());
215 instructions_.Add(new DeoptPcMarkerInstr(from_index));
216 }
217
218
219 void DeoptInfoBuilder::AddCopy(const Location& from_loc,
220 const Value& from_value,
221 const intptr_t to_index) {
222 DeoptInstr* deopt_instr = NULL;
223 if (from_loc.IsConstant()) {
224 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant());
225 deopt_instr = new DeoptConstantInstr(object_table_index);
226 } else if (from_loc.IsRegister()) {
227 deopt_instr = new DeoptRegisterInstr(from_loc.reg());
228 } else if (from_loc.IsStackSlot()) {
229 deopt_instr = new DeoptStackSlotInstr(from_loc.stack_index() + num_args_);
230 } else if (from_loc.IsInvalid()) {
231 ASSERT(from_value.IsConstant());
232 const Object& obj = from_value.AsConstant()->value();
233 intptr_t object_table_index = FindOrAddObjectInTable(obj);
234 deopt_instr = new DeoptConstantInstr(object_table_index);
235 } else {
236 UNREACHABLE();
237 }
238 ASSERT(to_index == instructions_.length());
239 instructions_.Add(deopt_instr);
240 }
241
242
243 void DeoptInfoBuilder::AddCallerFp(intptr_t to_index) {
244 ASSERT(to_index == instructions_.length());
245 instructions_.Add(new DeoptCallerFpInstr());
246 }
247
248
249 void DeoptInfoBuilder::AddCallerPc(intptr_t to_index) {
250 ASSERT(to_index == instructions_.length());
251 instructions_.Add(new DeoptCallerPcInstr());
252 }
253
254
255 RawDeoptInfo* DeoptInfoBuilder::CreateDeoptInfo() const {
256 const intptr_t len = instructions_.length();
257 const DeoptInfo& deopt_info = DeoptInfo::Handle(DeoptInfo::New(len));
258 for (intptr_t i = 0; i < len; i++) {
259 DeoptInstr* instr = instructions_[i];
260 deopt_info.SetAt(i, instr->kind(), instr->from_index());
261 }
262 return deopt_info.raw();
263 }
264
265 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698