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

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'. 'from_index' represents the local count >= 0, first
siva 2012/08/04 01:21:50 'from_index' to specified slots in the unoptimized
srdjan 2012/08/06 20:09:05 Done.
15 // argument being 0.
16 class DeoptStackSlotInstr : public DeoptInstr {
17 public:
18 explicit DeoptStackSlotInstr(intptr_t from_index)
19 : stack_slot_index_(from_index) {
20 ASSERT(stack_slot_index_ >= 0);
21 }
22
23 virtual intptr_t from_index() const { return stack_slot_index_; }
24 virtual DeoptInstr::Kind kind() const { return kStackSlot; }
25
26 virtual const char* ToCString() const {
27 intptr_t len = OS::SNPrint(NULL, 0, "s%d", stack_slot_index_);
28 char* chars = reinterpret_cast<char*>(
29 Isolate::Current()->current_zone()->Allocate(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 kReturnAddress; }
52
53 virtual const char* ToCString() const {
54 intptr_t len = OS::SNPrint(NULL, 0, "ret oti:%d", object_table_index_);
55 char* chars = reinterpret_cast<char*>(
56 Isolate::Current()->current_zone()->Allocate(len + 1));
57 OS::SNPrint(chars, len + 1, "ret oti:%d", object_table_index_);
58 return chars;
59 }
60
61 private:
62 const intptr_t object_table_index_;
63
64 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrInstr);
65 };
66
67
68 // Deoptimization instruction moving a constant stored at 'object_table_index'.
69 class DeoptConstantInstr : public DeoptInstr {
70 public:
71 explicit DeoptConstantInstr(intptr_t object_table_index)
72 : object_table_index_(object_table_index) {
73 ASSERT(object_table_index >= 0);
74 }
75
76 virtual intptr_t from_index() const { return object_table_index_; }
77 virtual DeoptInstr::Kind kind() const { return kConstant; }
78
79 virtual const char* ToCString() const {
80 intptr_t len = OS::SNPrint(NULL, 0, "const oti:%d", object_table_index_);
81 char* chars = reinterpret_cast<char*>(
82 Isolate::Current()->current_zone()->Allocate(len + 1));
83 OS::SNPrint(chars, len + 1, "const oti:%d", object_table_index_);
84 return chars;
85 }
86
87 private:
88 const intptr_t object_table_index_;
89
90 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr);
91 };
92
93
94 // Deoptimization instruction moving a register.
95 class DeoptRegisterInstr: public DeoptInstr {
96 public:
97 explicit DeoptRegisterInstr(intptr_t reg_as_int)
98 : reg_(static_cast<Register>(reg_as_int)) {}
99
100 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
101 virtual DeoptInstr::Kind kind() const { return kRegister; }
102
103 virtual const char* ToCString() const {
104 return Assembler::RegisterName(reg_);
105 }
106
107 private:
108 const Register reg_;
109
110 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr);
111 };
112
113
114 // Deoptimization instruction creating a PC marker for the code of
115 // function at 'object_table_index'.
116 class DeoptPcMarkerInstr : public DeoptInstr {
117 public:
118 explicit DeoptPcMarkerInstr(intptr_t object_table_index)
119 : object_table_index_(object_table_index) {
120 ASSERT(object_table_index >= 0);
121 }
122
123 virtual intptr_t from_index() const { return object_table_index_; }
124 virtual DeoptInstr::Kind kind() const { return kPcMarker; }
125
126 virtual const char* ToCString() const {
127 intptr_t len = OS::SNPrint(NULL, 0, "pcmark oti:%d", object_table_index_);
128 char* chars = reinterpret_cast<char*>(
129 Isolate::Current()->current_zone()->Allocate(len + 1));
130 OS::SNPrint(chars, len + 1, "pcmark oti:%d", object_table_index_);
131 return chars;
132 }
133
134 private:
135 intptr_t object_table_index_;
136
137 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr);
138 };
139
140
141 // Deoptimization instruction copying the caller saved FP from optimized frame.
142 class DeoptCallerFpInstr : public DeoptInstr {
143 public:
144 DeoptCallerFpInstr() {}
145
146 virtual intptr_t from_index() const { return 0; }
147 virtual DeoptInstr::Kind kind() const { return kCallerFp; }
148
149 virtual const char* ToCString() const { return "callerfp"; }
150
151 private:
152 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr);
153 };
154
155
156 // Deoptimization instruction copying the caller return address from optimzied
157 // frame.
158 class DeoptCallerPcInstr : public DeoptInstr {
159 public:
160 DeoptCallerPcInstr() {}
161
162 virtual intptr_t from_index() const { return 0; }
163 virtual DeoptInstr::Kind kind() const { return kCallerFp; }
164
165 virtual const char* ToCString() const { return "callerpc"; }
166
167 private:
168 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
169 };
170
171
172 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
173 Kind kind = static_cast<Kind>(kind_as_int);
174 switch (kind) {
175 case kStackSlot: return new DeoptStackSlotInstr(from_index);
176 case kReturnAddress: return new DeoptRetAddrInstr(from_index);
177 case kConstant: return new DeoptConstantInstr(from_index);
178 case kRegister: return new DeoptRegisterInstr(from_index);
179 case kPcMarker: return new DeoptPcMarkerInstr(from_index);
180 case kCallerFp: return new DeoptCallerFpInstr();
181 case kCallerPc: return new DeoptCallerPcInstr();
182 }
183 UNREACHABLE();
184 return NULL;
185 }
186
187
188 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const {
189 for (intptr_t i = 0; i < object_table_->length(); i++) {
190 if ((*object_table_)[i]->raw() == obj.raw()) {
191 return i;
192 }
193 }
194 // Add object.
195 const intptr_t result = object_table_->length();
196 object_table_->Add(&obj);
siva 2012/08/04 01:21:50 Need to assert obj is a Zone handle because you ar
srdjan 2012/08/06 20:09:05 Discussed and switched to GrowableObjectAray.
197 return result;
198 }
199
200
201 // Will be neeeded for inlined functions, currently trivial.
202 void DeoptInfoBuilder::AddReturnAddress(const Function& function,
203 intptr_t deopt_id) {
204 const intptr_t object_table_index = object_table_->length();
205 object_table_->Add(&function);
206 object_table_->Add(&Smi::ZoneHandle(Smi::New(deopt_id)));
207 instructions_.Add(new DeoptRetAddrInstr(object_table_index));
208 }
209
210
211 void DeoptInfoBuilder::AddPcMarker(const Function& function) {
212 // Function object was already added by AddReturnAddress, find it.
213 intptr_t from_index = FindOrAddObjectInTable(function);
214 instructions_.Add(new DeoptPcMarkerInstr(from_index));
215 }
216
217
218 void DeoptInfoBuilder::AddCopy(const Location& loc, const Value& value) {
siva 2012/08/04 01:21:50 The "to index" is implicit and you have made a com
srdjan 2012/08/06 20:09:05 Done.
219 DeoptInstr* deopt_instr = NULL;
220 if (loc.IsConstant()) {
221 const intptr_t object_table_index = FindOrAddObjectInTable(loc.constant());
222 deopt_instr = new DeoptConstantInstr(object_table_index);
223 } else if (loc.IsRegister()) {
224 deopt_instr = new DeoptRegisterInstr(loc.reg());
225 } else if (loc.IsStackSlot()) {
226 deopt_instr = new DeoptStackSlotInstr(loc.stack_index() + num_args_);
227 } else if (loc.IsInvalid()) {
228 ASSERT(value.IsConstant());
229 const Object& obj = value.AsConstant()->value();
230 const intptr_t object_table_index = FindOrAddObjectInTable(obj);
231 deopt_instr = new DeoptConstantInstr(object_table_index);
232 } else {
233 UNREACHABLE();
234 }
235
236 instructions_.Add(deopt_instr);
237 }
238
239
240 void DeoptInfoBuilder::AddCallerFp() {
241 instructions_.Add(new DeoptCallerFpInstr());
242 }
243
244
245 void DeoptInfoBuilder::AddCallerPc() {
246 instructions_.Add(new DeoptCallerPcInstr());
247 }
248
249
250 RawDeoptInfo* DeoptInfoBuilder::CreateDeoptInfo() {
251 const intptr_t len = instructions_.length();
252 const DeoptInfo& deopt_info = DeoptInfo::Handle(DeoptInfo::New(len));
253 for (intptr_t i = 0; i < len; i++) {
254 DeoptInstr* instr = instructions_[i];
255 deopt_info.SetAt(i, instr->kind(), instr->from_index());
256 }
257 return deopt_info.raw();
258 }
259
260 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698