blob: 02cfd4d9f326810c1df9e1fa767e3fd41e8c36a1 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2009 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_
29#define V8_IA32_MACRO_ASSEMBLER_IA32_H_
30
31#include "assembler.h"
32
33namespace v8 {
34namespace internal {
35
Kristian Monsen25f61362010-05-21 11:50:48 +010036// Flags used for the AllocateInNewSpace functions.
37enum AllocationFlags {
38 // No special flags.
39 NO_ALLOCATION_FLAGS = 0,
40 // Return the pointer to the allocated already tagged as a heap object.
41 TAG_OBJECT = 1 << 0,
42 // The content of the result register already contains the allocation top in
43 // new space.
44 RESULT_CONTAINS_TOP = 1 << 1
45};
46
Leon Clarkee46be812010-01-19 14:06:41 +000047// Convenience for platform-independent signatures. We do not normally
48// distinguish memory operands from other operands on ia32.
49typedef Operand MemOperand;
50
Steve Blocka7e24c12009-10-30 11:49:00 +000051// Forward declaration.
52class JumpTarget;
53
Steve Blocka7e24c12009-10-30 11:49:00 +000054// MacroAssembler implements a collection of frequently used macros.
55class MacroAssembler: public Assembler {
56 public:
57 MacroAssembler(void* buffer, int size);
58
59 // ---------------------------------------------------------------------------
60 // GC Support
61
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +010062 // For page containing |object| mark region covering |addr| dirty.
63 // RecordWriteHelper only works if the object is not in new
Steve Block6ded16b2010-05-10 14:33:55 +010064 // space.
65 void RecordWriteHelper(Register object,
66 Register addr,
67 Register scratch);
68
69 // Check if object is in new space.
70 // scratch can be object itself, but it will be clobbered.
71 void InNewSpace(Register object,
72 Register scratch,
73 Condition cc, // equal for new space, not_equal otherwise.
74 Label* branch);
75
Steve Block8defd9f2010-07-08 12:39:36 +010076 // For page containing |object| mark region covering [object+offset]
77 // dirty. |object| is the object being stored into, |value| is the
78 // object being stored. If offset is zero, then the scratch register
79 // contains the array index into the elements array represented as a
80 // Smi. All registers are clobbered by the operation. RecordWrite
81 // filters out smis so it does not update the write barrier if the
82 // value is a smi.
Steve Blocka7e24c12009-10-30 11:49:00 +000083 void RecordWrite(Register object,
84 int offset,
85 Register value,
86 Register scratch);
87
Steve Block8defd9f2010-07-08 12:39:36 +010088 // For page containing |object| mark region covering |address|
89 // dirty. |object| is the object being stored into, |value| is the
90 // object being stored. All registers are clobbered by the
91 // operation. RecordWrite filters out smis so it does not update the
92 // write barrier if the value is a smi.
93 void RecordWrite(Register object,
94 Register address,
95 Register value);
96
Steve Blocka7e24c12009-10-30 11:49:00 +000097#ifdef ENABLE_DEBUGGER_SUPPORT
98 // ---------------------------------------------------------------------------
99 // Debugger Support
100
101 void SaveRegistersToMemory(RegList regs);
102 void RestoreRegistersFromMemory(RegList regs);
103 void PushRegistersFromMemory(RegList regs);
104 void PopRegistersToMemory(RegList regs);
105 void CopyRegistersFromStackToMemory(Register base,
106 Register scratch,
107 RegList regs);
Andrei Popescu402d9372010-02-26 13:31:12 +0000108 void DebugBreak();
Steve Blocka7e24c12009-10-30 11:49:00 +0000109#endif
110
111 // ---------------------------------------------------------------------------
Steve Blockd0582a62009-12-15 09:54:21 +0000112 // Stack limit support
113
114 // Do simple test for stack overflow. This doesn't handle an overflow.
115 void StackLimitCheck(Label* on_stack_limit_hit);
116
117 // ---------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +0000118 // Activation frames
119
120 void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); }
121 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); }
122
123 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); }
124 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
125
Steve Blockd0582a62009-12-15 09:54:21 +0000126 // Enter specific kind of exit frame; either in normal or debug mode.
127 // Expects the number of arguments in register eax and
Steve Blocka7e24c12009-10-30 11:49:00 +0000128 // sets up the number of arguments in register edi and the pointer
129 // to the first argument in register esi.
Steve Blockd0582a62009-12-15 09:54:21 +0000130 void EnterExitFrame(ExitFrame::Mode mode);
131
132 void EnterApiExitFrame(ExitFrame::Mode mode, int stack_space, int argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000133
134 // Leave the current exit frame. Expects the return value in
135 // register eax:edx (untouched) and the pointer to the first
136 // argument in register esi.
Steve Blockd0582a62009-12-15 09:54:21 +0000137 void LeaveExitFrame(ExitFrame::Mode mode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000138
Steve Blockd0582a62009-12-15 09:54:21 +0000139 // Find the function context up the context chain.
140 void LoadContext(Register dst, int context_chain_length);
Steve Blocka7e24c12009-10-30 11:49:00 +0000141
142 // ---------------------------------------------------------------------------
143 // JavaScript invokes
144
145 // Invoke the JavaScript function code by either calling or jumping.
146 void InvokeCode(const Operand& code,
147 const ParameterCount& expected,
148 const ParameterCount& actual,
149 InvokeFlag flag);
150
151 void InvokeCode(Handle<Code> code,
152 const ParameterCount& expected,
153 const ParameterCount& actual,
154 RelocInfo::Mode rmode,
155 InvokeFlag flag);
156
157 // Invoke the JavaScript function in the given register. Changes the
158 // current context to the context in the function before invoking.
159 void InvokeFunction(Register function,
160 const ParameterCount& actual,
161 InvokeFlag flag);
162
Andrei Popescu402d9372010-02-26 13:31:12 +0000163 void InvokeFunction(JSFunction* function,
164 const ParameterCount& actual,
165 InvokeFlag flag);
166
Steve Blocka7e24c12009-10-30 11:49:00 +0000167 // Invoke specified builtin JavaScript function. Adds an entry to
168 // the unresolved list if the name does not resolve.
169 void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag);
170
171 // Store the code object for the given builtin in the target register.
172 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
173
174 // Expression support
175 void Set(Register dst, const Immediate& x);
176 void Set(const Operand& dst, const Immediate& x);
177
178 // Compare object type for heap object.
179 // Incoming register is heap_object and outgoing register is map.
180 void CmpObjectType(Register heap_object, InstanceType type, Register map);
181
182 // Compare instance type for map.
183 void CmpInstanceType(Register map, InstanceType type);
184
Andrei Popescu31002712010-02-23 13:46:05 +0000185 // Check if the map of an object is equal to a specified map and
186 // branch to label if not. Skip the smi check if not required
187 // (object is known to be a heap object)
188 void CheckMap(Register obj,
189 Handle<Map> map,
190 Label* fail,
191 bool is_heap_object);
192
Leon Clarkee46be812010-01-19 14:06:41 +0000193 // Check if the object in register heap_object is a string. Afterwards the
194 // register map contains the object map and the register instance_type
195 // contains the instance_type. The registers map and instance_type can be the
196 // same in which case it contains the instance type afterwards. Either of the
197 // registers map and instance_type can be the same as heap_object.
198 Condition IsObjectStringType(Register heap_object,
199 Register map,
200 Register instance_type);
201
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100202 // Check if a heap object's type is in the JSObject range, not including
203 // JSFunction. The object's map will be loaded in the map register.
204 // Any or all of the three registers may be the same.
205 // The contents of the scratch register will always be overwritten.
206 void IsObjectJSObjectType(Register heap_object,
207 Register map,
208 Register scratch,
209 Label* fail);
210
211 // The contents of the scratch register will be overwritten.
212 void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
213
Steve Blocka7e24c12009-10-30 11:49:00 +0000214 // FCmp is similar to integer cmp, but requires unsigned
215 // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
216 void FCmp();
217
Leon Clarkee46be812010-01-19 14:06:41 +0000218 // Smi tagging support.
219 void SmiTag(Register reg) {
220 ASSERT(kSmiTag == 0);
Steve Block6ded16b2010-05-10 14:33:55 +0100221 ASSERT(kSmiTagSize == 1);
222 add(reg, Operand(reg));
Leon Clarkee46be812010-01-19 14:06:41 +0000223 }
224 void SmiUntag(Register reg) {
225 sar(reg, kSmiTagSize);
226 }
227
Andrei Popescu402d9372010-02-26 13:31:12 +0000228 // Abort execution if argument is not a number. Used in debug code.
Steve Block6ded16b2010-05-10 14:33:55 +0100229 void AbortIfNotNumber(Register object);
230
231 // Abort execution if argument is not a smi. Used in debug code.
232 void AbortIfNotSmi(Register object);
Andrei Popescu402d9372010-02-26 13:31:12 +0000233
Steve Blocka7e24c12009-10-30 11:49:00 +0000234 // ---------------------------------------------------------------------------
235 // Exception handling
236
237 // Push a new try handler and link into try handler chain. The return
238 // address must be pushed before calling this helper.
239 void PushTryHandler(CodeLocation try_location, HandlerType type);
240
Leon Clarkee46be812010-01-19 14:06:41 +0000241 // Unlink the stack handler on top of the stack from the try handler chain.
242 void PopTryHandler();
Steve Blocka7e24c12009-10-30 11:49:00 +0000243
244 // ---------------------------------------------------------------------------
245 // Inline caching support
246
Steve Blocka7e24c12009-10-30 11:49:00 +0000247 // Generate code for checking access rights - used for security checks
248 // on access to global objects across environments. The holder register
249 // is left untouched, but the scratch register is clobbered.
250 void CheckAccessGlobalProxy(Register holder_reg,
251 Register scratch,
252 Label* miss);
253
254
255 // ---------------------------------------------------------------------------
256 // Allocation support
257
258 // Allocate an object in new space. If the new space is exhausted control
259 // continues at the gc_required label. The allocated object is returned in
260 // result and end of the new object is returned in result_end. The register
261 // scratch can be passed as no_reg in which case an additional object
262 // reference will be added to the reloc info. The returned pointers in result
263 // and result_end have not yet been tagged as heap objects. If
Steve Blockd0582a62009-12-15 09:54:21 +0000264 // result_contains_top_on_entry is true the content of result is known to be
Steve Blocka7e24c12009-10-30 11:49:00 +0000265 // the allocation top on entry (could be result_end from a previous call to
266 // AllocateInNewSpace). If result_contains_top_on_entry is true scratch
267 // should be no_reg as it is never used.
268 void AllocateInNewSpace(int object_size,
269 Register result,
270 Register result_end,
271 Register scratch,
272 Label* gc_required,
273 AllocationFlags flags);
274
275 void AllocateInNewSpace(int header_size,
276 ScaleFactor element_size,
277 Register element_count,
278 Register result,
279 Register result_end,
280 Register scratch,
281 Label* gc_required,
282 AllocationFlags flags);
283
284 void AllocateInNewSpace(Register object_size,
285 Register result,
286 Register result_end,
287 Register scratch,
288 Label* gc_required,
289 AllocationFlags flags);
290
291 // Undo allocation in new space. The object passed and objects allocated after
292 // it will no longer be allocated. Make sure that no pointers are left to the
293 // object(s) no longer allocated as they would be invalid when allocation is
294 // un-done.
295 void UndoAllocationInNewSpace(Register object);
296
Steve Block3ce2e202009-11-05 08:53:23 +0000297 // Allocate a heap number in new space with undefined value. The
298 // register scratch2 can be passed as no_reg; the others must be
299 // valid registers. Returns tagged pointer in result register, or
300 // jumps to gc_required if new space is full.
301 void AllocateHeapNumber(Register result,
302 Register scratch1,
303 Register scratch2,
304 Label* gc_required);
305
Steve Blockd0582a62009-12-15 09:54:21 +0000306 // Allocate a sequential string. All the header fields of the string object
307 // are initialized.
308 void AllocateTwoByteString(Register result,
309 Register length,
310 Register scratch1,
311 Register scratch2,
312 Register scratch3,
313 Label* gc_required);
314 void AllocateAsciiString(Register result,
315 Register length,
316 Register scratch1,
317 Register scratch2,
318 Register scratch3,
319 Label* gc_required);
320
321 // Allocate a raw cons string object. Only the map field of the result is
322 // initialized.
323 void AllocateConsString(Register result,
324 Register scratch1,
325 Register scratch2,
326 Label* gc_required);
327 void AllocateAsciiConsString(Register result,
328 Register scratch1,
329 Register scratch2,
330 Label* gc_required);
331
Steve Blocka7e24c12009-10-30 11:49:00 +0000332 // ---------------------------------------------------------------------------
333 // Support functions.
334
335 // Check if result is zero and op is negative.
336 void NegativeZeroTest(Register result, Register op, Label* then_label);
337
338 // Check if result is zero and op is negative in code using jump targets.
339 void NegativeZeroTest(CodeGenerator* cgen,
340 Register result,
341 Register op,
342 JumpTarget* then_target);
343
344 // Check if result is zero and any of op1 and op2 are negative.
345 // Register scratch is destroyed, and it must be different from op2.
346 void NegativeZeroTest(Register result, Register op1, Register op2,
347 Register scratch, Label* then_label);
348
349 // Try to get function prototype of a function and puts the value in
350 // the result register. Checks that the function really is a
351 // function and jumps to the miss label if the fast checks fail. The
352 // function register will be untouched; the other registers may be
353 // clobbered.
354 void TryGetFunctionPrototype(Register function,
355 Register result,
356 Register scratch,
357 Label* miss);
358
359 // Generates code for reporting that an illegal operation has
360 // occurred.
361 void IllegalOperation(int num_arguments);
362
363 // ---------------------------------------------------------------------------
364 // Runtime calls
365
Leon Clarkee46be812010-01-19 14:06:41 +0000366 // Call a code stub. Generate the code if necessary.
Steve Blocka7e24c12009-10-30 11:49:00 +0000367 void CallStub(CodeStub* stub);
368
Leon Clarkee46be812010-01-19 14:06:41 +0000369 // Call a code stub and return the code object called. Try to generate
370 // the code if necessary. Do not perform a GC but instead return a retry
371 // after GC failure.
372 Object* TryCallStub(CodeStub* stub);
373
374 // Tail call a code stub (jump). Generate the code if necessary.
Steve Blockd0582a62009-12-15 09:54:21 +0000375 void TailCallStub(CodeStub* stub);
376
Leon Clarkee46be812010-01-19 14:06:41 +0000377 // Tail call a code stub (jump) and return the code object called. Try to
378 // generate the code if necessary. Do not perform a GC but instead return
379 // a retry after GC failure.
380 Object* TryTailCallStub(CodeStub* stub);
381
Steve Blocka7e24c12009-10-30 11:49:00 +0000382 // Return from a code stub after popping its arguments.
383 void StubReturn(int argc);
384
385 // Call a runtime routine.
Steve Blocka7e24c12009-10-30 11:49:00 +0000386 void CallRuntime(Runtime::Function* f, int num_arguments);
387
Leon Clarke4515c472010-02-03 11:58:03 +0000388 // Call a runtime function, returning the CodeStub object called.
Leon Clarkee46be812010-01-19 14:06:41 +0000389 // Try to generate the stub code if necessary. Do not perform a GC
390 // but instead return a retry after GC failure.
391 Object* TryCallRuntime(Runtime::Function* f, int num_arguments);
392
Steve Blocka7e24c12009-10-30 11:49:00 +0000393 // Convenience function: Same as above, but takes the fid instead.
394 void CallRuntime(Runtime::FunctionId id, int num_arguments);
395
Andrei Popescu402d9372010-02-26 13:31:12 +0000396 // Convenience function: call an external reference.
397 void CallExternalReference(ExternalReference ref, int num_arguments);
398
Leon Clarkee46be812010-01-19 14:06:41 +0000399 // Convenience function: Same as above, but takes the fid instead.
400 Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments);
401
Steve Blocka7e24c12009-10-30 11:49:00 +0000402 // Tail call of a runtime routine (jump).
Steve Block6ded16b2010-05-10 14:33:55 +0100403 // Like JumpToExternalReference, but also takes care of passing the number
404 // of parameters.
405 void TailCallExternalReference(const ExternalReference& ext,
406 int num_arguments,
407 int result_size);
408
409 // Convenience function: tail call a runtime routine (jump).
410 void TailCallRuntime(Runtime::FunctionId fid,
Steve Blocka7e24c12009-10-30 11:49:00 +0000411 int num_arguments,
412 int result_size);
413
Steve Block6ded16b2010-05-10 14:33:55 +0100414 // Before calling a C-function from generated code, align arguments on stack.
415 // After aligning the frame, arguments must be stored in esp[0], esp[4],
416 // etc., not pushed. The argument count assumes all arguments are word sized.
417 // Some compilers/platforms require the stack to be aligned when calling
418 // C++ code.
419 // Needs a scratch register to do some arithmetic. This register will be
420 // trashed.
421 void PrepareCallCFunction(int num_arguments, Register scratch);
422
423 // Calls a C function and cleans up the space for arguments allocated
424 // by PrepareCallCFunction. The called function is not allowed to trigger a
425 // garbage collection, since that might move the code and invalidate the
426 // return address (unless this is somehow accounted for by the called
427 // function).
428 void CallCFunction(ExternalReference function, int num_arguments);
429 void CallCFunction(Register function, int num_arguments);
430
Steve Blockd0582a62009-12-15 09:54:21 +0000431 void PushHandleScope(Register scratch);
432
433 // Pops a handle scope using the specified scratch register and
434 // ensuring that saved register, it is not no_reg, is left unchanged.
435 void PopHandleScope(Register saved, Register scratch);
436
Leon Clarkee46be812010-01-19 14:06:41 +0000437 // As PopHandleScope, but does not perform a GC. Instead, returns a
438 // retry after GC failure object if GC is necessary.
439 Object* TryPopHandleScope(Register saved, Register scratch);
440
Steve Blocka7e24c12009-10-30 11:49:00 +0000441 // Jump to a runtime routine.
Steve Block6ded16b2010-05-10 14:33:55 +0100442 void JumpToExternalReference(const ExternalReference& ext);
Steve Blocka7e24c12009-10-30 11:49:00 +0000443
444
445 // ---------------------------------------------------------------------------
446 // Utilities
447
448 void Ret();
449
Leon Clarkee46be812010-01-19 14:06:41 +0000450 // Emit code to discard a non-negative number of pointer-sized elements
451 // from the stack, clobbering only the esp register.
452 void Drop(int element_count);
453
454 void Call(Label* target) { call(target); }
455
456 void Move(Register target, Handle<Object> value);
457
Steve Blocka7e24c12009-10-30 11:49:00 +0000458 Handle<Object> CodeObject() { return code_object_; }
459
460
461 // ---------------------------------------------------------------------------
462 // StatsCounter support
463
464 void SetCounter(StatsCounter* counter, int value);
465 void IncrementCounter(StatsCounter* counter, int value);
466 void DecrementCounter(StatsCounter* counter, int value);
Leon Clarked91b9f72010-01-27 17:25:45 +0000467 void IncrementCounter(Condition cc, StatsCounter* counter, int value);
468 void DecrementCounter(Condition cc, StatsCounter* counter, int value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000469
470
471 // ---------------------------------------------------------------------------
472 // Debugging
473
474 // Calls Abort(msg) if the condition cc is not satisfied.
475 // Use --debug_code to enable.
476 void Assert(Condition cc, const char* msg);
477
478 // Like Assert(), but always enabled.
479 void Check(Condition cc, const char* msg);
480
481 // Print a message to stdout and abort execution.
482 void Abort(const char* msg);
483
Steve Block6ded16b2010-05-10 14:33:55 +0100484 // Check that the stack is aligned.
485 void CheckStackAlignment();
486
Steve Blocka7e24c12009-10-30 11:49:00 +0000487 // Verify restrictions about code generated in stubs.
488 void set_generating_stub(bool value) { generating_stub_ = value; }
489 bool generating_stub() { return generating_stub_; }
490 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
491 bool allow_stub_calls() { return allow_stub_calls_; }
492
Leon Clarked91b9f72010-01-27 17:25:45 +0000493 // ---------------------------------------------------------------------------
494 // String utilities.
495
Andrei Popescu402d9372010-02-26 13:31:12 +0000496 // Check whether the instance type represents a flat ascii string. Jump to the
497 // label if not. If the instance type can be scratched specify same register
498 // for both instance type and scratch.
499 void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type,
500 Register scratch,
Steve Block6ded16b2010-05-10 14:33:55 +0100501 Label* on_not_flat_ascii_string);
Andrei Popescu402d9372010-02-26 13:31:12 +0000502
Leon Clarked91b9f72010-01-27 17:25:45 +0000503 // Checks if both objects are sequential ASCII strings, and jumps to label
504 // if either is not.
505 void JumpIfNotBothSequentialAsciiStrings(Register object1,
506 Register object2,
507 Register scratch1,
508 Register scratch2,
Steve Block6ded16b2010-05-10 14:33:55 +0100509 Label* on_not_flat_ascii_strings);
Leon Clarked91b9f72010-01-27 17:25:45 +0000510
Steve Blocka7e24c12009-10-30 11:49:00 +0000511 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000512 bool generating_stub_;
513 bool allow_stub_calls_;
Andrei Popescu31002712010-02-23 13:46:05 +0000514 // This handle will be patched with the code object on installation.
515 Handle<Object> code_object_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000516
517 // Helper functions for generating invokes.
518 void InvokePrologue(const ParameterCount& expected,
519 const ParameterCount& actual,
520 Handle<Code> code_constant,
521 const Operand& code_operand,
522 Label* done,
523 InvokeFlag flag);
524
Steve Blocka7e24c12009-10-30 11:49:00 +0000525 // Activation support.
526 void EnterFrame(StackFrame::Type type);
527 void LeaveFrame(StackFrame::Type type);
528
Steve Blockd0582a62009-12-15 09:54:21 +0000529 void EnterExitFramePrologue(ExitFrame::Mode mode);
530 void EnterExitFrameEpilogue(ExitFrame::Mode mode, int argc);
531
Steve Blocka7e24c12009-10-30 11:49:00 +0000532 // Allocation support helpers.
533 void LoadAllocationTopHelper(Register result,
534 Register result_end,
535 Register scratch,
536 AllocationFlags flags);
537 void UpdateAllocationTopHelper(Register result_end, Register scratch);
Leon Clarkee46be812010-01-19 14:06:41 +0000538
539 // Helper for PopHandleScope. Allowed to perform a GC and returns
540 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
541 // possibly returns a failure object indicating an allocation failure.
542 Object* PopHandleScopeHelper(Register saved,
543 Register scratch,
544 bool gc_allowed);
Steve Blocka7e24c12009-10-30 11:49:00 +0000545};
546
547
548// The code patcher is used to patch (typically) small parts of code e.g. for
549// debugging and other types of instrumentation. When using the code patcher
550// the exact number of bytes specified must be emitted. Is not legal to emit
551// relocation information. If any of these constraints are violated it causes
552// an assertion.
553class CodePatcher {
554 public:
555 CodePatcher(byte* address, int size);
556 virtual ~CodePatcher();
557
558 // Macro assembler to emit code.
559 MacroAssembler* masm() { return &masm_; }
560
561 private:
562 byte* address_; // The address of the code being patched.
563 int size_; // Number of bytes of the expected patch size.
564 MacroAssembler masm_; // Macro assembler used to generate the code.
565};
566
567
568// -----------------------------------------------------------------------------
569// Static helper functions.
570
571// Generate an Operand for loading a field from an object.
572static inline Operand FieldOperand(Register object, int offset) {
573 return Operand(object, offset - kHeapObjectTag);
574}
575
576
577// Generate an Operand for loading an indexed field from an object.
578static inline Operand FieldOperand(Register object,
579 Register index,
580 ScaleFactor scale,
581 int offset) {
582 return Operand(object, index, scale, offset - kHeapObjectTag);
583}
584
585
586#ifdef GENERATED_CODE_COVERAGE
587extern void LogGeneratedCodeCoverage(const char* file_line);
588#define CODE_COVERAGE_STRINGIFY(x) #x
589#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
590#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
591#define ACCESS_MASM(masm) { \
592 byte* ia32_coverage_function = \
593 reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
594 masm->pushfd(); \
595 masm->pushad(); \
596 masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \
597 masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \
598 masm->pop(eax); \
599 masm->popad(); \
600 masm->popfd(); \
601 } \
602 masm->
603#else
604#define ACCESS_MASM(masm) masm->
605#endif
606
607
608} } // namespace v8::internal
609
610#endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_