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

Side by Side Diff: src/macro-assembler-ia32.cc

Issue 9328: Initial (stub) port of jump targets to the ARM platform.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 12 years, 1 month 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
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 18 matching lines...) Expand all
29 29
30 #include "bootstrapper.h" 30 #include "bootstrapper.h"
31 #include "codegen-inl.h" 31 #include "codegen-inl.h"
32 #include "debug.h" 32 #include "debug.h"
33 #include "runtime.h" 33 #include "runtime.h"
34 #include "serialize.h" 34 #include "serialize.h"
35 35
36 namespace v8 { namespace internal { 36 namespace v8 { namespace internal {
37 37
38 // ------------------------------------------------------------------------- 38 // -------------------------------------------------------------------------
39 // VirtualFrame implementation.
40
41 #define __ masm_->
42
43 VirtualFrame::VirtualFrame(CodeGenerator* cgen) {
44 ASSERT(cgen->scope() != NULL);
45
46 masm_ = cgen->masm();
47 frame_local_count_ = cgen->scope()->num_stack_slots();
48 parameter_count_ = cgen->scope()->num_parameters();
49 height_ = 0;
50 }
51
52
53 VirtualFrame::VirtualFrame(VirtualFrame* original) {
54 ASSERT(original != NULL);
55
56 masm_ = original->masm_;
57 frame_local_count_ = original->frame_local_count_;
58 parameter_count_ = original->parameter_count_;
59 height_ = original->height_;
60 }
61
62
63 void VirtualFrame::Forget(int count) {
64 ASSERT(count >= 0);
65 ASSERT(height_ >= count);
66 height_ -= count;
67 }
68
69
70 void VirtualFrame::MergeTo(VirtualFrame* expected) {
71 ASSERT(masm_ == expected->masm_);
72 ASSERT(frame_local_count_ == expected->frame_local_count_);
73 ASSERT(parameter_count_ == expected->parameter_count_);
74 ASSERT(height_ == expected->height_);
75 }
76
77
78 void VirtualFrame::Enter() {
79 Comment cmnt(masm_, "[ Enter JS frame");
80 __ push(ebp);
81 __ mov(ebp, Operand(esp));
82
83 // Store the context and the function in the frame.
84 __ push(esi);
85 __ push(edi);
86
87 // Clear the function slot when generating debug code.
88 if (FLAG_debug_code) {
89 __ Set(edi, Immediate(reinterpret_cast<int>(kZapValue)));
90 }
91 }
92
93
94 void VirtualFrame::Exit() {
95 Comment cmnt(masm_, "[ Exit JS frame");
96 // Record the location of the JS exit code for patching when setting
97 // break point.
98 __ RecordJSReturn();
99
100 // Avoid using the leave instruction here, because it is too
101 // short. We need the return sequence to be a least the size of a
102 // call instruction to support patching the exit code in the
103 // debugger. See VisitReturnStatement for the full return sequence.
104 __ mov(esp, Operand(ebp));
105 __ pop(ebp);
106 }
107
108
109 void VirtualFrame::AllocateLocals() {
110 if (frame_local_count_ > 0) {
111 Comment cmnt(masm_, "[ Allocate space for locals");
112 __ Set(eax, Immediate(Factory::undefined_value()));
113 for (int i = 0; i < frame_local_count_; i++) {
114 __ push(eax);
115 }
116 }
117 }
118
119
120 // -------------------------------------------------------------------------
121 // JumpTarget implementation.
122
123 JumpTarget::JumpTarget(CodeGenerator* cgen) {
124 ASSERT(cgen != NULL);
125 expected_frame_ = NULL;
126 code_generator_ = cgen;
127 masm_ = cgen->masm();
128 }
129
130
131 JumpTarget::JumpTarget()
132 : expected_frame_(NULL),
133 code_generator_(NULL),
134 masm_(NULL) {
135 }
136
137
138 void JumpTarget::set_code_generator(CodeGenerator* cgen) {
139 ASSERT(cgen != NULL);
140 ASSERT(code_generator_ == NULL);
141 code_generator_ = cgen;
142 masm_ = cgen->masm();
143 }
144
145
146 bool JumpTarget::IsActualFunctionReturn() {
147 return (this == &code_generator_->function_return_ &&
148 !code_generator_->function_return_is_shadowed_);
149 }
150
151
152 void JumpTarget::Jump() {
153 // Precondition: there is a current frame. There may or may not be an
154 // expected frame at the label.
155 ASSERT(code_generator_ != NULL);
156 ASSERT(masm_ != NULL);
157
158 VirtualFrame* current_frame = code_generator_->frame();
159 ASSERT(current_frame != NULL);
160
161 if (expected_frame_ == NULL) {
162 expected_frame_ = current_frame;
163 code_generator_->set_frame(NULL);
164 // The frame at the actual function return will always have height
165 // zero.
166 if (IsActualFunctionReturn()) expected_frame_->height_ = 0;
167 } else {
168 // No code needs to be emitted to merge to the expected frame at the
169 // actual function return.
170 if (!IsActualFunctionReturn()) current_frame->MergeTo(expected_frame_);
171 code_generator_->delete_frame();
172 }
173
174 __ jmp(&label_);
175 // Postcondition: there is no current frame but there is an expected frame
176 // at the label.
177 }
178
179
180 void JumpTarget::Branch(Condition cc, Hint hint) {
181 // Precondition: there is a current frame. There may or may not be an
182 // expected frame at the label.
183 ASSERT(code_generator_ != NULL);
184 ASSERT(masm_ != NULL);
185
186 VirtualFrame* current_frame = code_generator_->frame();
187 ASSERT(current_frame != NULL);
188
189 if (expected_frame_ == NULL) {
190 expected_frame_ = new VirtualFrame(current_frame);
191 // The frame at the actual function return will always have height
192 // zero.
193 if (IsActualFunctionReturn()) expected_frame_->height_ = 0;
194 } else {
195 // No code needs to be emitted to merge to the expected frame at the
196 // actual function return.
197 if (!IsActualFunctionReturn()) current_frame->MergeTo(expected_frame_);
198 }
199
200 __ j(cc, &label_, hint);
201 // Postcondition: there is both a current frame and an expected frame at
202 // the label and they match.
203 }
204
205
206 void JumpTarget::Call() {
207 // Precondition: there is a current frame, and there is no expected frame
208 // at the label.
209 ASSERT(code_generator_ != NULL);
210 ASSERT(masm_ != NULL);
211 ASSERT(!IsActualFunctionReturn());
212
213 VirtualFrame* current_frame = code_generator_->frame();
214 ASSERT(current_frame != NULL);
215 ASSERT(expected_frame_ == NULL);
216
217 expected_frame_ = new VirtualFrame(current_frame);
218 // Adjust the expected frame's height to account for the return address
219 // pushed by the call instruction.
220 expected_frame_->height_++;
221
222 __ call(&label_);
223
224 // Postcondition: there is both a current frame and an expected frame at
225 // the label. The current frame is one shorter than the one at the label
226 // (which contains the 'return address', ie, the eip register and possibly
227 // cs register).
228 }
229
230
231 void JumpTarget::Bind() {
232 ASSERT(code_generator_ != NULL);
233 ASSERT(masm_ != NULL);
234
235 // Precondition: there is either a current frame or an expected frame at
236 // the label (and possibly both). The label is unbound.
237 VirtualFrame* current_frame = code_generator_->frame();
238 ASSERT(current_frame != NULL || expected_frame_ != NULL);
239 ASSERT(!label_.is_bound());
240
241 if (expected_frame_ == NULL) {
242 expected_frame_ = new VirtualFrame(current_frame);
243 // The frame at the actual function return will always have height
244 // zero.
245 if (IsActualFunctionReturn()) expected_frame_->height_ = 0;
246 } else if (current_frame == NULL) {
247 code_generator_->set_frame(new VirtualFrame(expected_frame_));
248 } else {
249 // No code needs to be emitted to merge to the expected frame at the
250 // actual function return.
251 if (!IsActualFunctionReturn()) current_frame->MergeTo(expected_frame_);
252 }
253
254 __ bind(&label_);
255 // Postcondition: there is both a current frame and an expected frame at
256 // the label and they match. The label is bound.
257 }
258
259
260 // -------------------------------------------------------------------------
261 // ShadowTarget implementation.
262
263 ShadowTarget::ShadowTarget(JumpTarget* original) {
264 ASSERT(original != NULL);
265 original_target_ = original;
266 original_pos_ = original->label()->pos_;
267 original_expected_frame_ = original->expected_frame();
268
269 // We do not call Unuse() on the orginal jump target, because we do not
270 // want to delete the expected frame.
271 original->label()->pos_ = 0;
272 original->set_expected_frame(NULL);
273 #ifdef DEBUG
274 is_shadowing_ = true;
275 #endif
276 }
277
278
279 void ShadowTarget::StopShadowing() {
280 ASSERT(is_shadowing_);
281 ASSERT(is_unused());
282
283 set_code_generator(original_target_->code_generator());
284 label_.pos_ = original_target_->label()->pos_;
285 expected_frame_ = original_target_->expected_frame();
286
287 original_target_->label()->pos_ = original_pos_;
288 original_target_->set_expected_frame(original_expected_frame_);
289
290 #ifdef DEBUG
291 is_shadowing_ = false;
292 #endif
293 }
294
295 #undef __
296
297
298 // -------------------------------------------------------------------------
299 // MacroAssembler implementation. 39 // MacroAssembler implementation.
300 40
301 MacroAssembler::MacroAssembler(void* buffer, int size) 41 MacroAssembler::MacroAssembler(void* buffer, int size)
302 : Assembler(buffer, size), 42 : Assembler(buffer, size),
303 unresolved_(0), 43 unresolved_(0),
304 generating_stub_(false), 44 generating_stub_(false),
305 allow_stub_calls_(true) { 45 allow_stub_calls_(true) {
306 } 46 }
307 47
308 48
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 // Indicate that code has changed. 1007 // Indicate that code has changed.
1268 CPU::FlushICache(address_, size_); 1008 CPU::FlushICache(address_, size_);
1269 1009
1270 // Check that the code was patched as expected. 1010 // Check that the code was patched as expected.
1271 ASSERT(masm_.pc_ == address_ + size_); 1011 ASSERT(masm_.pc_ == address_ + size_);
1272 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 1012 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
1273 } 1013 }
1274 1014
1275 1015
1276 } } // namespace v8::internal 1016 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698