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

Side by Side Diff: src/codegen-ia32.h

Issue 8961: Merge change list off bleeding_edge into toiger branch. (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
« no previous file with comments | « src/codegen.cc ('k') | src/codegen-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 25 matching lines...) Expand all
36 class DeferredCode; 36 class DeferredCode;
37 37
38 // Mode to overwrite BinaryExpression values. 38 // Mode to overwrite BinaryExpression values.
39 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; 39 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
40 40
41 enum InitState { CONST_INIT, NOT_CONST_INIT }; 41 enum InitState { CONST_INIT, NOT_CONST_INIT };
42 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; 42 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
43 43
44 44
45 // ------------------------------------------------------------------------- 45 // -------------------------------------------------------------------------
46 // Virtual frame
47
48 class VirtualFrame BASE_EMBEDDED {
49 public:
50 explicit VirtualFrame(CodeGenerator* cgen);
51
52 void Enter();
53 void Exit();
54
55 void AllocateLocals();
56
57 Operand Top() const { return Operand(esp, 0); }
58
59 Operand Element(int index) const {
60 return Operand(esp, index * kPointerSize);
61 }
62
63 Operand Local(int index) const {
64 ASSERT(0 <= index && index < frame_local_count_);
65 return Operand(ebp, kLocal0Offset - index * kPointerSize);
66 }
67
68 Operand Function() const { return Operand(ebp, kFunctionOffset); }
69
70 Operand Context() const { return Operand(ebp, kContextOffset); }
71
72 Operand Parameter(int index) const {
73 ASSERT(-1 <= index && index < parameter_count_);
74 return Operand(ebp, (1 + parameter_count_ - index) * kPointerSize);
75 }
76
77 Operand Receiver() const { return Parameter(-1); }
78
79 inline void Drop(int count);
80
81 inline void Pop();
82 inline void Pop(Register reg);
83 inline void Pop(Operand operand);
84
85 inline void Push(Register reg);
86 inline void Push(Operand operand);
87 inline void Push(Immediate immediate);
88
89 private:
90 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
91 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
92 static const int kContextOffset = StandardFrameConstants::kContextOffset;
93
94 MacroAssembler* masm_;
95 int frame_local_count_;
96 int parameter_count_;
97 };
98
99
100 // -------------------------------------------------------------------------
101 // Reference support 46 // Reference support
102 47
103 // A reference is a C++ stack-allocated object that keeps an ECMA 48 // A reference is a C++ stack-allocated object that keeps an ECMA
104 // reference on the execution stack while in scope. For variables 49 // reference on the execution stack while in scope. For variables
105 // the reference is empty, indicating that it isn't necessary to 50 // the reference is empty, indicating that it isn't necessary to
106 // store state on the stack for keeping track of references to those. 51 // store state on the stack for keeping track of references to those.
107 // For properties, we keep either one (named) or two (indexed) values 52 // For properties, we keep either one (named) or two (indexed) values
108 // on the execution stack to represent the reference. 53 // on the execution stack to represent the reference.
109 54
110 class Reference BASE_EMBEDDED { 55 class Reference BASE_EMBEDDED {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 CodeGenerator* cgen_; 91 CodeGenerator* cgen_;
147 Expression* expression_; 92 Expression* expression_;
148 Type type_; 93 Type type_;
149 }; 94 };
150 95
151 96
152 // ------------------------------------------------------------------------- 97 // -------------------------------------------------------------------------
153 // Code generation state 98 // Code generation state
154 99
155 // The state is passed down the AST by the code generator (and back up, in 100 // The state is passed down the AST by the code generator (and back up, in
156 // the form of the state of the label pair). It is threaded through the 101 // the form of the state of the jump target pair). It is threaded through
157 // call stack. Constructing a state implicitly pushes it on the owning code 102 // the call stack. Constructing a state implicitly pushes it on the owning
158 // generator's stack of states, and destroying one implicitly pops it. 103 // code generator's stack of states, and destroying one implicitly pops it.
104 //
105 // The code generator state is only used for expressions, so statements have
106 // the initial state.
159 107
160 class CodeGenState BASE_EMBEDDED { 108 class CodeGenState BASE_EMBEDDED {
161 public: 109 public:
162 // Create an initial code generator state. Destroying the initial state 110 // Create an initial code generator state. Destroying the initial state
163 // leaves the code generator with a NULL state. 111 // leaves the code generator with a NULL state.
164 explicit CodeGenState(CodeGenerator* owner); 112 explicit CodeGenState(CodeGenerator* owner);
165 113
166 // Create a code generator state based on a code generator's current 114 // Create a code generator state based on a code generator's current
167 // state. The new state has its own access type and pair of branch 115 // state. The new state may or may not be inside a typeof, and has its
168 // labels, and no reference. 116 // own pair of branch targets.
169 CodeGenState(CodeGenerator* owner, 117 CodeGenState(CodeGenerator* owner,
170 TypeofState typeof_state, 118 TypeofState typeof_state,
171 Label* true_target, 119 JumpTarget* true_target,
172 Label* false_target); 120 JumpTarget* false_target);
173 121
174 // Destroy a code generator state and restore the owning code generator's 122 // Destroy a code generator state and restore the owning code generator's
175 // previous state. 123 // previous state.
176 ~CodeGenState(); 124 ~CodeGenState();
177 125
126 // Accessors for the state.
178 TypeofState typeof_state() const { return typeof_state_; } 127 TypeofState typeof_state() const { return typeof_state_; }
179 Label* true_target() const { return true_target_; } 128 JumpTarget* true_target() const { return true_target_; }
180 Label* false_target() const { return false_target_; } 129 JumpTarget* false_target() const { return false_target_; }
181 130
182 private: 131 private:
132 // The owning code generator.
183 CodeGenerator* owner_; 133 CodeGenerator* owner_;
134
135 // A flag indicating whether we are compiling the immediate subexpression
136 // of a typeof expression.
184 TypeofState typeof_state_; 137 TypeofState typeof_state_;
185 Label* true_target_; 138
186 Label* false_target_; 139 // A pair of jump targets in case the expression has a control-flow
140 // effect.
141 JumpTarget* true_target_;
142 JumpTarget* false_target_;
143
144 // The previous state of the owning code generator, restored when
145 // this state is destroyed.
187 CodeGenState* previous_; 146 CodeGenState* previous_;
188 }; 147 };
189 148
190 149
191 150
192 151
193 // ------------------------------------------------------------------------- 152 // -------------------------------------------------------------------------
194 // CodeGenerator 153 // CodeGenerator
195 154
196 class CodeGenerator: public Visitor { 155 class CodeGenerator: public Visitor {
(...skipping 11 matching lines...) Expand all
208 int end_position, 167 int end_position,
209 bool is_expression, 168 bool is_expression,
210 bool is_toplevel, 169 bool is_toplevel,
211 Handle<Script> script); 170 Handle<Script> script);
212 171
213 // Accessors 172 // Accessors
214 MacroAssembler* masm() { return masm_; } 173 MacroAssembler* masm() { return masm_; }
215 174
216 VirtualFrame* frame() const { return frame_; } 175 VirtualFrame* frame() const { return frame_; }
217 176
177 void set_frame(VirtualFrame* frame) { frame_ = frame; }
178
179 void delete_frame() {
180 delete frame_;
181 frame_ = NULL;
182 }
183
218 CodeGenState* state() { return state_; } 184 CodeGenState* state() { return state_; }
219 void set_state(CodeGenState* state) { state_ = state; } 185 void set_state(CodeGenState* state) { state_ = state; }
220 186
221 void AddDeferred(DeferredCode* code) { deferred_.Add(code); } 187 void AddDeferred(DeferredCode* code) { deferred_.Add(code); }
222 188
223 private: 189 private:
224 // Construction/Destruction 190 // Construction/Destruction
225 CodeGenerator(int buffer_size, Handle<Script> script, bool is_eval); 191 CodeGenerator(int buffer_size, Handle<Script> script, bool is_eval);
226 virtual ~CodeGenerator() { delete masm_; } 192 virtual ~CodeGenerator() { delete masm_; }
227 193
228 // Accessors 194 // Accessors
229 Scope* scope() const { return scope_; } 195 Scope* scope() const { return scope_; }
230 196
231 void ProcessDeferred(); 197 void ProcessDeferred();
232 198
233 bool is_eval() { return is_eval_; } 199 bool is_eval() { return is_eval_; }
234 200
235 // State 201 // State
236 bool has_cc() const { return cc_reg_ >= 0; } 202 bool has_cc() const { return cc_reg_ >= 0; }
237 TypeofState typeof_state() const { return state_->typeof_state(); } 203 TypeofState typeof_state() const { return state_->typeof_state(); }
238 Label* true_target() const { return state_->true_target(); } 204 JumpTarget* true_target() const { return state_->true_target(); }
239 Label* false_target() const { return state_->false_target(); } 205 JumpTarget* false_target() const { return state_->false_target(); }
240 206
241 // Track loop nesting level. 207 // Track loop nesting level.
242 int loop_nesting() const { return loop_nesting_; } 208 int loop_nesting() const { return loop_nesting_; }
243 void IncrementLoopNesting() { loop_nesting_++; } 209 void IncrementLoopNesting() { loop_nesting_++; }
244 void DecrementLoopNesting() { loop_nesting_--; } 210 void DecrementLoopNesting() { loop_nesting_--; }
245 211
246 212
247 // Node visitors. 213 // Node visitors.
214 void VisitStatements(ZoneList<Statement*>* statements);
215
248 #define DEF_VISIT(type) \ 216 #define DEF_VISIT(type) \
249 void Visit##type(type* node); 217 void Visit##type(type* node);
250 NODE_LIST(DEF_VISIT) 218 NODE_LIST(DEF_VISIT)
251 #undef DEF_VISIT 219 #undef DEF_VISIT
252 220
253 // Main code generation function 221 // Main code generation function
254 void GenCode(FunctionLiteral* fun); 222 void GenCode(FunctionLiteral* fun);
255 223
256 // The following are used by class Reference. 224 // The following are used by class Reference.
257 void LoadReference(Reference* ref); 225 void LoadReference(Reference* ref);
258 void UnloadReference(Reference* ref); 226 void UnloadReference(Reference* ref);
259 227
260 Operand ContextOperand(Register context, int index) const { 228 Operand ContextOperand(Register context, int index) const {
261 return Operand(context, Context::SlotOffset(index)); 229 return Operand(context, Context::SlotOffset(index));
262 } 230 }
263 231
264 Operand SlotOperand(Slot* slot, Register tmp); 232 Operand SlotOperand(Slot* slot, Register tmp);
265 233
266 234
267 // Expressions 235 // Expressions
268 Operand GlobalObject() const { 236 Operand GlobalObject() const {
269 return ContextOperand(esi, Context::GLOBAL_INDEX); 237 return ContextOperand(esi, Context::GLOBAL_INDEX);
270 } 238 }
271 239
272 void LoadCondition(Expression* x, 240 void LoadCondition(Expression* x,
273 TypeofState typeof_state, 241 TypeofState typeof_state,
274 Label* true_target, 242 JumpTarget* true_target,
275 Label* false_target, 243 JumpTarget* false_target,
276 bool force_cc); 244 bool force_cc);
277 void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF); 245 void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF);
278 void LoadGlobal(); 246 void LoadGlobal();
279 void LoadGlobalReceiver(Register scratch); 247 void LoadGlobalReceiver(Register scratch);
280 248
281 // Read a value from a slot and leave it on top of the expression stack. 249 // Read a value from a slot and leave it on top of the expression stack.
282 void LoadFromSlot(Slot* slot, TypeofState typeof_state); 250 void LoadFromSlot(Slot* slot, TypeofState typeof_state);
283 251
284 // Special code for typeof expressions: Unfortunately, we must 252 // Special code for typeof expressions: Unfortunately, we must
285 // be careful when loading the expression in 'typeof' 253 // be careful when loading the expression in 'typeof'
286 // expressions. We are not allowed to throw reference errors for 254 // expressions. We are not allowed to throw reference errors for
287 // non-existing properties of the global object, so we must make it 255 // non-existing properties of the global object, so we must make it
288 // look like an explicit property access, instead of an access 256 // look like an explicit property access, instead of an access
289 // through the context chain. 257 // through the context chain.
290 void LoadTypeofExpression(Expression* x); 258 void LoadTypeofExpression(Expression* x);
291 259
292 void ToBoolean(Label* true_target, Label* false_target); 260 void ToBoolean(JumpTarget* true_target, JumpTarget* false_target);
293 261
294 void GenericBinaryOperation(Token::Value op, 262 void GenericBinaryOperation(Token::Value op,
295 StaticType* type, 263 StaticType* type,
296 const OverwriteMode overwrite_mode = NO_OVERWRITE); 264 const OverwriteMode overwrite_mode = NO_OVERWRITE);
297 265
298 void Comparison(Condition cc, bool strict = false); 266 void Comparison(Condition cc, bool strict = false);
299 267
300 // Inline small integer literals. To prevent long attacker-controlled byte 268 // Inline small integer literals. To prevent long attacker-controlled byte
301 // sequences, we only inline small Smis. 269 // sequences, we only inline small Smis.
302 static const int kMaxSmiInlinedBits = 16; 270 static const int kMaxSmiInlinedBits = 16;
303 bool IsInlineSmi(Literal* literal); 271 bool IsInlineSmi(Literal* literal);
304 void SmiComparison(Condition cc, Handle<Object> value, bool strict = false); 272 void SmiComparison(Condition cc, Handle<Object> value, bool strict = false);
305 void SmiOperation(Token::Value op, 273 void SmiOperation(Token::Value op,
306 StaticType* type, 274 StaticType* type,
307 Handle<Object> value, 275 Handle<Object> value,
308 bool reversed, 276 bool reversed,
309 OverwriteMode overwrite_mode); 277 OverwriteMode overwrite_mode);
310 278
311 void CallWithArguments(ZoneList<Expression*>* arguments, int position); 279 void CallWithArguments(ZoneList<Expression*>* arguments, int position);
312 280
313 // Control flow 281 // Control flow
314 void Branch(bool if_true, Label* L); 282 void Branch(bool if_true, JumpTarget* target);
315 void CheckStack(); 283 void CheckStack();
316 void CleanStack(int num_bytes); 284 void CleanStack(int num_bytes);
317 285
318 bool CheckForInlineRuntimeCall(CallRuntime* node); 286 bool CheckForInlineRuntimeCall(CallRuntime* node);
319 Handle<JSFunction> BuildBoilerplate(FunctionLiteral* node); 287 Handle<JSFunction> BuildBoilerplate(FunctionLiteral* node);
320 void ProcessDeclarations(ZoneList<Declaration*>* declarations); 288 void ProcessDeclarations(ZoneList<Declaration*>* declarations);
321 289
322 Handle<Code> ComputeCallInitialize(int argc); 290 Handle<Code> ComputeCallInitialize(int argc);
323 291
324 // Declare global variables and functions in the given array of 292 // Declare global variables and functions in the given array of
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 // is optimal compared to the default code generated for a switch statement 340 // is optimal compared to the default code generated for a switch statement
373 // on that platform. 341 // on that platform.
374 int FastCaseSwitchMinCaseCount(); 342 int FastCaseSwitchMinCaseCount();
375 343
376 // Allocate a jump table and create code to jump through it. 344 // Allocate a jump table and create code to jump through it.
377 // Should call GenerateFastCaseSwitchCases to generate the code for 345 // Should call GenerateFastCaseSwitchCases to generate the code for
378 // all the cases at the appropriate point. 346 // all the cases at the appropriate point.
379 void GenerateFastCaseSwitchJumpTable(SwitchStatement* node, 347 void GenerateFastCaseSwitchJumpTable(SwitchStatement* node,
380 int min_index, 348 int min_index,
381 int range, 349 int range,
382 Label* fail_label, 350 JumpTarget* fail_label,
383 Vector<Label*> case_targets, 351 Vector<JumpTarget*> case_targets,
384 Vector<Label> case_labels); 352 Vector<JumpTarget> case_labels);
385 353
386 // Generate the code for cases for the fast case switch. 354 // Generate the code for cases for the fast case switch.
387 // Called by GenerateFastCaseSwitchJumpTable. 355 // Called by GenerateFastCaseSwitchJumpTable.
388 void GenerateFastCaseSwitchCases(SwitchStatement* node, 356 void GenerateFastCaseSwitchCases(SwitchStatement* node,
389 Vector<Label> case_labels); 357 Vector<JumpTarget> case_labels,
358 JumpTarget* table_start);
390 359
391 // Fast support for constant-Smi switches. 360 // Fast support for constant-Smi switches.
392 void GenerateFastCaseSwitchStatement(SwitchStatement* node, 361 void GenerateFastCaseSwitchStatement(SwitchStatement* node,
393 int min_index, 362 int min_index,
394 int range, 363 int range,
395 int default_index); 364 int default_index);
396 365
397 // Fast support for constant-Smi switches. Tests whether switch statement 366 // Fast support for constant-Smi switches. Tests whether switch statement
398 // permits optimization and calls GenerateFastCaseSwitch if it does. 367 // permits optimization and calls GenerateFastCaseSwitch if it does.
399 // Returns true if the fast-case switch was generated, and false if not. 368 // Returns true if the fast-case switch was generated, and false if not.
(...skipping 14 matching lines...) Expand all
414 383
415 // Code generation state 384 // Code generation state
416 Scope* scope_; 385 Scope* scope_;
417 VirtualFrame* frame_; 386 VirtualFrame* frame_;
418 Condition cc_reg_; 387 Condition cc_reg_;
419 CodeGenState* state_; 388 CodeGenState* state_;
420 bool is_inside_try_; 389 bool is_inside_try_;
421 int break_stack_height_; 390 int break_stack_height_;
422 int loop_nesting_; 391 int loop_nesting_;
423 392
424 // Labels 393 // Jump targets.
425 Label function_return_; 394 // The target of the return from the function.
395 JumpTarget function_return_;
396
397 // True if the function return is shadowed (ie, jumping to the target
398 // function_return_ does not jump to the true function return, but rather
399 // to some unlinking code).
400 bool function_return_is_shadowed_;
426 401
427 friend class VirtualFrame; 402 friend class VirtualFrame;
403 friend class JumpTarget;
428 friend class Reference; 404 friend class Reference;
429 405
430 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); 406 DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
431 }; 407 };
432 408
433 409
434 } } // namespace v8::internal 410 } } // namespace v8::internal
435 411
436 #endif // V8_CODEGEN_IA32_H_ 412 #endif // V8_CODEGEN_IA32_H_
OLDNEW
« no previous file with comments | « src/codegen.cc ('k') | src/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698