My favorites | Sign in
v8
Project Home Downloads Wiki Issues Source Code Search
Checkout   Browse   Changes  
Changes to /trunk/src/ia32/macro-assembler-ia32.h
r12669 vs. r12683 Compare: vs.  Format:
Revision r12683
Go to: 
Project members, sign in to write a code review
/trunk/src/ia32/macro-assembler-ia32.h   r12669 /trunk/src/ia32/macro-assembler-ia32.h   r12683
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_ 28 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_
29 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_ 29 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_
30 30
31 #include "assembler.h" 31 #include "assembler.h"
32 #include "frames.h" 32 #include "frames.h"
33 #include "v8globals.h" 33 #include "v8globals.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 // Flags used for the AllocateInNewSpace functions. 38 // Flags used for the AllocateInNewSpace functions.
39 enum AllocationFlags { 39 enum AllocationFlags {
40 // No special flags. 40 // No special flags.
41 NO_ALLOCATION_FLAGS = 0, 41 NO_ALLOCATION_FLAGS = 0,
42 // Return the pointer to the allocated already tagged as a heap object. 42 // Return the pointer to the allocated already tagged as a heap object.
43 TAG_OBJECT = 1 << 0, 43 TAG_OBJECT = 1 << 0,
44 // The content of the result register already contains the allocation top in 44 // The content of the result register already contains the allocation top in
45 // new space. 45 // new space.
46 RESULT_CONTAINS_TOP = 1 << 1 46 RESULT_CONTAINS_TOP = 1 << 1
47 }; 47 };
48 48
49 49
50 // Convenience for platform-independent signatures. We do not normally 50 // Convenience for platform-independent signatures. We do not normally
51 // distinguish memory operands from other operands on ia32. 51 // distinguish memory operands from other operands on ia32.
52 typedef Operand MemOperand; 52 typedef Operand MemOperand;
53 53
54 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; 54 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
55 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; 55 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
56 56
57 57
58 bool AreAliased(Register r1, Register r2, Register r3, Register r4); 58 bool AreAliased(Register r1, Register r2, Register r3, Register r4);
59 59
60 60
61 // MacroAssembler implements a collection of frequently used macros. 61 // MacroAssembler implements a collection of frequently used macros.
62 class MacroAssembler: public Assembler { 62 class MacroAssembler: public Assembler {
63 public: 63 public:
64 // The isolate parameter can be NULL if the macro assembler should 64 // The isolate parameter can be NULL if the macro assembler should
65 // not use isolate-dependent functionality. In this case, it's the 65 // not use isolate-dependent functionality. In this case, it's the
66 // responsibility of the caller to never invoke such function on the 66 // responsibility of the caller to never invoke such function on the
67 // macro assembler. 67 // macro assembler.
68 MacroAssembler(Isolate* isolate, void* buffer, int size); 68 MacroAssembler(Isolate* isolate, void* buffer, int size);
69 69
70 // --------------------------------------------------------------------------- 70 // ---------------------------------------------------------------------------
71 // GC Support 71 // GC Support
72 enum RememberedSetFinalAction { 72 enum RememberedSetFinalAction {
73 kReturnAtEnd, 73 kReturnAtEnd,
74 kFallThroughAtEnd 74 kFallThroughAtEnd
75 }; 75 };
76 76
77 // Record in the remembered set the fact that we have a pointer to new space 77 // Record in the remembered set the fact that we have a pointer to new space
78 // at the address pointed to by the addr register. Only works if addr is not 78 // at the address pointed to by the addr register. Only works if addr is not
79 // in new space. 79 // in new space.
80 void RememberedSetHelper(Register object, // Used for debug code. 80 void RememberedSetHelper(Register object, // Used for debug code.
81 Register addr, 81 Register addr,
82 Register scratch, 82 Register scratch,
83 SaveFPRegsMode save_fp, 83 SaveFPRegsMode save_fp,
84 RememberedSetFinalAction and_then); 84 RememberedSetFinalAction and_then);
85 85
86 void CheckPageFlag(Register object, 86 void CheckPageFlag(Register object,
87 Register scratch, 87 Register scratch,
88 int mask, 88 int mask,
89 Condition cc, 89 Condition cc,
90 Label* condition_met, 90 Label* condition_met,
91 Label::Distance condition_met_distance = Label::kFar); 91 Label::Distance condition_met_distance = Label::kFar);
92 92
93 void CheckPageFlagForMap( 93 void CheckPageFlagForMap(
94 Handle<Map> map, 94 Handle<Map> map,
95 int mask, 95 int mask,
96 Condition cc, 96 Condition cc,
97 Label* condition_met, 97 Label* condition_met,
98 Label::Distance condition_met_distance = Label::kFar); 98 Label::Distance condition_met_distance = Label::kFar);
99 99
100 // Check if object is in new space. Jumps if the object is not in new space. 100 // Check if object is in new space. Jumps if the object is not in new space.
101 // The register scratch can be object itself, but scratch will be clobbered. 101 // The register scratch can be object itself, but scratch will be clobbered.
102 void JumpIfNotInNewSpace(Register object, 102 void JumpIfNotInNewSpace(Register object,
103 Register scratch, 103 Register scratch,
104 Label* branch, 104 Label* branch,
105 Label::Distance distance = Label::kFar) { 105 Label::Distance distance = Label::kFar) {
106 InNewSpace(object, scratch, zero, branch, distance); 106 InNewSpace(object, scratch, zero, branch, distance);
107 } 107 }
108 108
109 // Check if object is in new space. Jumps if the object is in new space. 109 // Check if object is in new space. Jumps if the object is in new space.
110 // The register scratch can be object itself, but it will be clobbered. 110 // The register scratch can be object itself, but it will be clobbered.
111 void JumpIfInNewSpace(Register object, 111 void JumpIfInNewSpace(Register object,
112 Register scratch, 112 Register scratch,
113 Label* branch, 113 Label* branch,
114 Label::Distance distance = Label::kFar) { 114 Label::Distance distance = Label::kFar) {
115 InNewSpace(object, scratch, not_zero, branch, distance); 115 InNewSpace(object, scratch, not_zero, branch, distance);
116 } 116 }
117 117
118 // Check if an object has a given incremental marking color. Also uses ecx! 118 // Check if an object has a given incremental marking color. Also uses ecx!
119 void HasColor(Register object, 119 void HasColor(Register object,
120 Register scratch0, 120 Register scratch0,
121 Register scratch1, 121 Register scratch1,
122 Label* has_color, 122 Label* has_color,
123 Label::Distance has_color_distance, 123 Label::Distance has_color_distance,
124 int first_bit, 124 int first_bit,
125 int second_bit); 125 int second_bit);
126 126
127 void JumpIfBlack(Register object, 127 void JumpIfBlack(Register object,
128 Register scratch0, 128 Register scratch0,
129 Register scratch1, 129 Register scratch1,
130 Label* on_black, 130 Label* on_black,
131 Label::Distance on_black_distance = Label::kFar); 131 Label::Distance on_black_distance = Label::kFar);
132 132
133 // Checks the color of an object. If the object is already grey or black 133 // Checks the color of an object. If the object is already grey or black
134 // then we just fall through, since it is already live. If it is white and 134 // then we just fall through, since it is already live. If it is white and
135 // we can determine that it doesn't need to be scanned, then we just mark it 135 // we can determine that it doesn't need to be scanned, then we just mark it
136 // black and fall through. For the rest we jump to the label so the 136 // black and fall through. For the rest we jump to the label so the
137 // incremental marker can fix its assumptions. 137 // incremental marker can fix its assumptions.
138 void EnsureNotWhite(Register object, 138 void EnsureNotWhite(Register object,
139 Register scratch1, 139 Register scratch1,
140 Register scratch2, 140 Register scratch2,
141 Label* object_is_white_and_not_data, 141 Label* object_is_white_and_not_data,
142 Label::Distance distance); 142 Label::Distance distance);
143 143
144 // Notify the garbage collector that we wrote a pointer into an object. 144 // Notify the garbage collector that we wrote a pointer into an object.
145 // |object| is the object being stored into, |value| is the object being 145 // |object| is the object being stored into, |value| is the object being
146 // stored. value and scratch registers are clobbered by the operation. 146 // stored. value and scratch registers are clobbered by the operation.
147 // The offset is the offset from the start of the object, not the offset from 147 // The offset is the offset from the start of the object, not the offset from
148 // the tagged HeapObject pointer. For use with FieldOperand(reg, off). 148 // the tagged HeapObject pointer. For use with FieldOperand(reg, off).
149 void RecordWriteField( 149 void RecordWriteField(
150 Register object, 150 Register object,
151 int offset, 151 int offset,
152 Register value, 152 Register value,
153 Register scratch, 153 Register scratch,
154 SaveFPRegsMode save_fp, 154 SaveFPRegsMode save_fp,
155 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 155 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
156 SmiCheck smi_check = INLINE_SMI_CHECK); 156 SmiCheck smi_check = INLINE_SMI_CHECK);
157 157
158 // As above, but the offset has the tag presubtracted. For use with 158 // As above, but the offset has the tag presubtracted. For use with
159 // Operand(reg, off). 159 // Operand(reg, off).
160 void RecordWriteContextSlot( 160 void RecordWriteContextSlot(
161 Register context, 161 Register context,
162 int offset, 162 int offset,
163 Register value, 163 Register value,
164 Register scratch, 164 Register scratch,
165 SaveFPRegsMode save_fp, 165 SaveFPRegsMode save_fp,
166 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 166 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
167 SmiCheck smi_check = INLINE_SMI_CHECK) { 167 SmiCheck smi_check = INLINE_SMI_CHECK) {
168 RecordWriteField(context, 168 RecordWriteField(context,
169 offset + kHeapObjectTag, 169 offset + kHeapObjectTag,
170 value, 170 value,
171 scratch, 171 scratch,
172 save_fp, 172 save_fp,
173 remembered_set_action, 173 remembered_set_action,
174 smi_check); 174 smi_check);
175 } 175 }
176 176
177 // Notify the garbage collector that we wrote a pointer into a fixed array. 177 // Notify the garbage collector that we wrote a pointer into a fixed array.
178 // |array| is the array being stored into, |value| is the 178 // |array| is the array being stored into, |value| is the
179 // object being stored. |index| is the array index represented as a 179 // object being stored. |index| is the array index represented as a
180 // Smi. All registers are clobbered by the operation RecordWriteArray 180 // Smi. All registers are clobbered by the operation RecordWriteArray
181 // filters out smis so it does not update the write barrier if the 181 // filters out smis so it does not update the write barrier if the
182 // value is a smi. 182 // value is a smi.
183 void RecordWriteArray( 183 void RecordWriteArray(
184 Register array, 184 Register array,
185 Register value, 185 Register value,
186 Register index, 186 Register index,
187 SaveFPRegsMode save_fp, 187 SaveFPRegsMode save_fp,
188 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 188 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
189 SmiCheck smi_check = INLINE_SMI_CHECK); 189 SmiCheck smi_check = INLINE_SMI_CHECK);
190 190
191 // For page containing |object| mark region covering |address| 191 // For page containing |object| mark region covering |address|
192 // dirty. |object| is the object being stored into, |value| is the 192 // dirty. |object| is the object being stored into, |value| is the
193 // object being stored. The address and value registers are clobbered by the 193 // object being stored. The address and value registers are clobbered by the
194 // operation. RecordWrite filters out smis so it does not update the 194 // operation. RecordWrite filters out smis so it does not update the
195 // write barrier if the value is a smi. 195 // write barrier if the value is a smi.
196 void RecordWrite( 196 void RecordWrite(
197 Register object, 197 Register object,
198 Register address, 198 Register address,
199 Register value, 199 Register value,
200 SaveFPRegsMode save_fp, 200 SaveFPRegsMode save_fp,
201 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 201 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
202 SmiCheck smi_check = INLINE_SMI_CHECK); 202 SmiCheck smi_check = INLINE_SMI_CHECK);
203 203
204 // For page containing |object| mark the region covering the object's map 204 // For page containing |object| mark the region covering the object's map
205 // dirty. |object| is the object being stored into, |map| is the Map object 205 // dirty. |object| is the object being stored into, |map| is the Map object
206 // that was stored. 206 // that was stored.
207 void RecordWriteForMap( 207 void RecordWriteForMap(
208 Register object, 208 Register object,
209 Handle<Map> map, 209 Handle<Map> map,
210 Register scratch1, 210 Register scratch1,
211 Register scratch2, 211 Register scratch2,
212 SaveFPRegsMode save_fp); 212 SaveFPRegsMode save_fp);
213 213
214 #ifdef ENABLE_DEBUGGER_SUPPORT 214 #ifdef ENABLE_DEBUGGER_SUPPORT
215 // --------------------------------------------------------------------------- 215 // ---------------------------------------------------------------------------
216 // Debugger Support 216 // Debugger Support
217 217
218 void DebugBreak(); 218 void DebugBreak();
219 #endif 219 #endif
220 220
221 // Enter specific kind of exit frame. Expects the number of 221 // Enter specific kind of exit frame. Expects the number of
222 // arguments in register eax and sets up the number of arguments in 222 // arguments in register eax and sets up the number of arguments in
223 // register edi and the pointer to the first argument in register 223 // register edi and the pointer to the first argument in register
224 // esi. 224 // esi.
225 void EnterExitFrame(bool save_doubles); 225 void EnterExitFrame(bool save_doubles);
226 226
227 void EnterApiExitFrame(int argc); 227 void EnterApiExitFrame(int argc);
228 228
229 // Leave the current exit frame. Expects the return value in 229 // Leave the current exit frame. Expects the return value in
230 // register eax:edx (untouched) and the pointer to the first 230 // register eax:edx (untouched) and the pointer to the first
231 // argument in register esi. 231 // argument in register esi.
232 void LeaveExitFrame(bool save_doubles); 232 void LeaveExitFrame(bool save_doubles);
233 233
234 // Leave the current exit frame. Expects the return value in 234 // Leave the current exit frame. Expects the return value in
235 // register eax (untouched). 235 // register eax (untouched).
236 void LeaveApiExitFrame(); 236 void LeaveApiExitFrame();
237 237
238 // Find the function context up the context chain. 238 // Find the function context up the context chain.
239 void LoadContext(Register dst, int context_chain_length); 239 void LoadContext(Register dst, int context_chain_length);
240 240
241 // Conditionally load the cached Array transitioned map of type 241 // Conditionally load the cached Array transitioned map of type
242 // transitioned_kind from the native context if the map in register 242 // transitioned_kind from the native context if the map in register
243 // map_in_out is the cached Array map in the native context of 243 // map_in_out is the cached Array map in the native context of
244 // expected_kind. 244 // expected_kind.
245 void LoadTransitionedArrayMapConditional( 245 void LoadTransitionedArrayMapConditional(
246 ElementsKind expected_kind, 246 ElementsKind expected_kind,
247 ElementsKind transitioned_kind, 247 ElementsKind transitioned_kind,
248 Register map_in_out, 248 Register map_in_out,
249 Register scratch, 249 Register scratch,
250 Label* no_map_match); 250 Label* no_map_match);
251 251
252 // Load the initial map for new Arrays from a JSFunction. 252 // Load the initial map for new Arrays from a JSFunction.
253 void LoadInitialArrayMap(Register function_in, 253 void LoadInitialArrayMap(Register function_in,
254 Register scratch, 254 Register scratch,
255 Register map_out, 255 Register map_out,
256 bool can_have_holes); 256 bool can_have_holes);
257 257
258 // Load the global function with the given index. 258 // Load the global function with the given index.
259 void LoadGlobalFunction(int index, Register function); 259 void LoadGlobalFunction(int index, Register function);
260 260
261 // Load the initial map from the global function. The registers 261 // Load the initial map from the global function. The registers
262 // function and map can be the same. 262 // function and map can be the same.
263 void LoadGlobalFunctionInitialMap(Register function, Register map); 263 void LoadGlobalFunctionInitialMap(Register function, Register map);
264 264
265 // Push and pop the registers that can hold pointers. 265 // Push and pop the registers that can hold pointers.
266 void PushSafepointRegisters() { pushad(); } 266 void PushSafepointRegisters() { pushad(); }
267 void PopSafepointRegisters() { popad(); } 267 void PopSafepointRegisters() { popad(); }
268 // Store the value in register/immediate src in the safepoint 268 // Store the value in register/immediate src in the safepoint
269 // register stack slot for register dst. 269 // register stack slot for register dst.
270 void StoreToSafepointRegisterSlot(Register dst, Register src); 270 void StoreToSafepointRegisterSlot(Register dst, Register src);
271 void StoreToSafepointRegisterSlot(Register dst, Immediate src); 271 void StoreToSafepointRegisterSlot(Register dst, Immediate src);
272 void LoadFromSafepointRegisterSlot(Register dst, Register src); 272 void LoadFromSafepointRegisterSlot(Register dst, Register src);
273 273
274 void LoadHeapObject(Register result, Handle<HeapObject> object); 274 void LoadHeapObject(Register result, Handle<HeapObject> object);
275 void PushHeapObject(Handle<HeapObject> object); 275 void PushHeapObject(Handle<HeapObject> object);
276 276
277 void LoadObject(Register result, Handle<Object> object) { 277 void LoadObject(Register result, Handle<Object> object) {
278 if (object->IsHeapObject()) { 278 if (object->IsHeapObject()) {
279 LoadHeapObject(result, Handle<HeapObject>::cast(object)); 279 LoadHeapObject(result, Handle<HeapObject>::cast(object));
280 } else { 280 } else {
281 Set(result, Immediate(object)); 281 Set(result, Immediate(object));
282 } 282 }
283 } 283 }
284 284
285 // --------------------------------------------------------------------------- 285 // ---------------------------------------------------------------------------
286 // JavaScript invokes 286 // JavaScript invokes
287 287
288 // Set up call kind marking in ecx. The method takes ecx as an 288 // Set up call kind marking in ecx. The method takes ecx as an
289 // explicit first parameter to make the code more readable at the 289 // explicit first parameter to make the code more readable at the
290 // call sites. 290 // call sites.
291 void SetCallKind(Register dst, CallKind kind); 291 void SetCallKind(Register dst, CallKind kind);
292 292
293 // Invoke the JavaScript function code by either calling or jumping. 293 // Invoke the JavaScript function code by either calling or jumping.
294 void InvokeCode(Register code, 294 void InvokeCode(Register code,
295 const ParameterCount& expected, 295 const ParameterCount& expected,
296 const ParameterCount& actual, 296 const ParameterCount& actual,
297 InvokeFlag flag, 297 InvokeFlag flag,
298 const CallWrapper& call_wrapper, 298 const CallWrapper& call_wrapper,
299 CallKind call_kind) { 299 CallKind call_kind) {
300 InvokeCode(Operand(code), expected, actual, flag, call_wrapper, call_kind); 300 InvokeCode(Operand(code), expected, actual, flag, call_wrapper, call_kind);
301 } 301 }
302 302
303 void InvokeCode(const Operand& code, 303 void InvokeCode(const Operand& code,
304 const ParameterCount& expected, 304 const ParameterCount& expected,
305 const ParameterCount& actual, 305 const ParameterCount& actual,
306 InvokeFlag flag, 306 InvokeFlag flag,
307 const CallWrapper& call_wrapper, 307 const CallWrapper& call_wrapper,
308 CallKind call_kind); 308 CallKind call_kind);
309 309
310 void InvokeCode(Handle<Code> code, 310 void InvokeCode(Handle<Code> code,
311 const ParameterCount& expected, 311 const ParameterCount& expected,
312 const ParameterCount& actual, 312 const ParameterCount& actual,
313 RelocInfo::Mode rmode, 313 RelocInfo::Mode rmode,
314 InvokeFlag flag, 314 InvokeFlag flag,
315 const CallWrapper& call_wrapper, 315 const CallWrapper& call_wrapper,
316 CallKind call_kind); 316 CallKind call_kind);
317 317
318 // Invoke the JavaScript function in the given register. Changes the 318 // Invoke the JavaScript function in the given register. Changes the
319 // current context to the context in the function before invoking. 319 // current context to the context in the function before invoking.
320 void InvokeFunction(Register function, 320 void InvokeFunction(Register function,
321 const ParameterCount& actual, 321 const ParameterCount& actual,
322 InvokeFlag flag, 322 InvokeFlag flag,
323 const CallWrapper& call_wrapper, 323 const CallWrapper& call_wrapper,
324 CallKind call_kind); 324 CallKind call_kind);
325 325
326 void InvokeFunction(Handle<JSFunction> function, 326 void InvokeFunction(Handle<JSFunction> function,
327 const ParameterCount& actual, 327 const ParameterCount& actual,
328 InvokeFlag flag, 328 InvokeFlag flag,
329 const CallWrapper& call_wrapper, 329 const CallWrapper& call_wrapper,
330 CallKind call_kind); 330 CallKind call_kind);
331 331
332 // Invoke specified builtin JavaScript function. Adds an entry to 332 // Invoke specified builtin JavaScript function. Adds an entry to
333 // the unresolved list if the name does not resolve. 333 // the unresolved list if the name does not resolve.
334 void InvokeBuiltin(Builtins::JavaScript id, 334 void InvokeBuiltin(Builtins::JavaScript id,
335 InvokeFlag flag, 335 InvokeFlag flag,
336 const CallWrapper& call_wrapper = NullCallWrapper()); 336 const CallWrapper& call_wrapper = NullCallWrapper());
337 337
338 // Store the function for the given builtin in the target register. 338 // Store the function for the given builtin in the target register.
339 void GetBuiltinFunction(Register target, Builtins::JavaScript id); 339 void GetBuiltinFunction(Register target, Builtins::JavaScript id);
340 340
341 // Store the code object for the given builtin in the target register. 341 // Store the code object for the given builtin in the target register.
342 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 342 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
343 343
344 // Expression support 344 // Expression support
345 void Set(Register dst, const Immediate& x); 345 void Set(Register dst, const Immediate& x);
346 void Set(const Operand& dst, const Immediate& x); 346 void Set(const Operand& dst, const Immediate& x);
347 347
348 // Support for constant splitting. 348 // Support for constant splitting.
349 bool IsUnsafeImmediate(const Immediate& x); 349 bool IsUnsafeImmediate(const Immediate& x);
350 void SafeSet(Register dst, const Immediate& x); 350 void SafeSet(Register dst, const Immediate& x);
351 void SafePush(const Immediate& x); 351 void SafePush(const Immediate& x);
352 352
353 // Compare against a known root, e.g. undefined, null, true, ... 353 // Compare against a known root, e.g. undefined, null, true, ...
354 void CompareRoot(Register with, Heap::RootListIndex index); 354 void CompareRoot(Register with, Heap::RootListIndex index);
355 void CompareRoot(const Operand& with, Heap::RootListIndex index); 355 void CompareRoot(const Operand& with, Heap::RootListIndex index);
356 356
357 // Compare object type for heap object. 357 // Compare object type for heap object.
358 // Incoming register is heap_object and outgoing register is map. 358 // Incoming register is heap_object and outgoing register is map.
359 void CmpObjectType(Register heap_object, InstanceType type, Register map); 359 void CmpObjectType(Register heap_object, InstanceType type, Register map);
360 360
361 // Compare instance type for map. 361 // Compare instance type for map.
362 void CmpInstanceType(Register map, InstanceType type); 362 void CmpInstanceType(Register map, InstanceType type);
363 363
364 // Check if a map for a JSObject indicates that the object has fast elements. 364 // Check if a map for a JSObject indicates that the object has fast elements.
365 // Jump to the specified label if it does not. 365 // Jump to the specified label if it does not.
366 void CheckFastElements(Register map, 366 void CheckFastElements(Register map,
367 Label* fail, 367 Label* fail,
368 Label::Distance distance = Label::kFar); 368 Label::Distance distance = Label::kFar);
369 369
370 // Check if a map for a JSObject indicates that the object can have both smi 370 // Check if a map for a JSObject indicates that the object can have both smi
371 // and HeapObject elements. Jump to the specified label if it does not. 371 // and HeapObject elements. Jump to the specified label if it does not.
372 void CheckFastObjectElements(Register map, 372 void CheckFastObjectElements(Register map,
373 Label* fail, 373 Label* fail,
374 Label::Distance distance = Label::kFar); 374 Label::Distance distance = Label::kFar);
375 375
376 // Check if a map for a JSObject indicates that the object has fast smi only 376 // Check if a map for a JSObject indicates that the object has fast smi only
377 // elements. Jump to the specified label if it does not. 377 // elements. Jump to the specified label if it does not.
378 void CheckFastSmiElements(Register map, 378 void CheckFastSmiElements(Register map,
379 Label* fail, 379 Label* fail,
380 Label::Distance distance = Label::kFar); 380 Label::Distance distance = Label::kFar);
381 381
382 // Check to see if maybe_number can be stored as a double in 382 // Check to see if maybe_number can be stored as a double in
383 // FastDoubleElements. If it can, store it at the index specified by key in 383 // FastDoubleElements. If it can, store it at the index specified by key in
384 // the FastDoubleElements array elements, otherwise jump to fail. 384 // the FastDoubleElements array elements, otherwise jump to fail.
385 void StoreNumberToDoubleElements(Register maybe_number, 385 void StoreNumberToDoubleElements(Register maybe_number,
386 Register elements, 386 Register elements,
387 Register key, 387 Register key,
388 Register scratch1, 388 Register scratch1,
389 XMMRegister scratch2, 389 XMMRegister scratch2,
390 Label* fail, 390 Label* fail,
391 bool specialize_for_processor); 391 bool specialize_for_processor);
392 392
393 // Compare an object's map with the specified map and its transitioned 393 // Compare an object's map with the specified map and its transitioned
394 // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. FLAGS are set with 394 // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. FLAGS are set with
395 // result of map compare. If multiple map compares are required, the compare 395 // result of map compare. If multiple map compares are required, the compare
396 // sequences branches to early_success. 396 // sequences branches to early_success.
397 void CompareMap(Register obj, 397 void CompareMap(Register obj,
398 Handle<Map> map, 398 Handle<Map> map,
399 Label* early_success, 399 Label* early_success,
400 CompareMapMode mode = REQUIRE_EXACT_MAP); 400 CompareMapMode mode = REQUIRE_EXACT_MAP);
401 401
402 // Check if the map of an object is equal to a specified map and branch to 402 // Check if the map of an object is equal to a specified map and branch to
403 // label if not. Skip the smi check if not required (object is known to be a 403 // label if not. Skip the smi check if not required (object is known to be a
404 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match 404 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
405 // against maps that are ElementsKind transition maps of the specified map. 405 // against maps that are ElementsKind transition maps of the specified map.
406 void CheckMap(Register obj, 406 void CheckMap(Register obj,
407 Handle<Map> map, 407 Handle<Map> map,
408 Label* fail, 408 Label* fail,
409 SmiCheckType smi_check_type, 409 SmiCheckType smi_check_type,
410 CompareMapMode mode = REQUIRE_EXACT_MAP); 410 CompareMapMode mode = REQUIRE_EXACT_MAP);
411 411
412 // Check if the map of an object is equal to a specified map and branch to a 412 // Check if the map of an object is equal to a specified map and branch to a
413 // specified target if equal. Skip the smi check if not required (object is 413 // specified target if equal. Skip the smi check if not required (object is
414 // known to be a heap object) 414 // known to be a heap object)
415 void DispatchMap(Register obj, 415 void DispatchMap(Register obj,
416 Handle<Map> map, 416 Handle<Map> map,
417 Handle<Code> success, 417 Handle<Code> success,
418 SmiCheckType smi_check_type); 418 SmiCheckType smi_check_type);
419 419
420 // Check if the object in register heap_object is a string. Afterwards the 420 // Check if the object in register heap_object is a string. Afterwards the
421 // register map contains the object map and the register instance_type 421 // register map contains the object map and the register instance_type
422 // contains the instance_type. The registers map and instance_type can be the 422 // contains the instance_type. The registers map and instance_type can be the
423 // same in which case it contains the instance type afterwards. Either of the 423 // same in which case it contains the instance type afterwards. Either of the
424 // registers map and instance_type can be the same as heap_object. 424 // registers map and instance_type can be the same as heap_object.
425 Condition IsObjectStringType(Register heap_object, 425 Condition IsObjectStringType(Register heap_object,
426 Register map, 426 Register map,
427 Register instance_type); 427 Register instance_type);
428 428
429 // Check if a heap object's type is in the JSObject range, not including 429 // Check if a heap object's type is in the JSObject range, not including
430 // JSFunction. The object's map will be loaded in the map register. 430 // JSFunction. The object's map will be loaded in the map register.
431 // Any or all of the three registers may be the same. 431 // Any or all of the three registers may be the same.
432 // The contents of the scratch register will always be overwritten. 432 // The contents of the scratch register will always be overwritten.
433 void IsObjectJSObjectType(Register heap_object, 433 void IsObjectJSObjectType(Register heap_object,
434 Register map, 434 Register map,
435 Register scratch, 435 Register scratch,
436 Label* fail); 436 Label* fail);
437 437
438 // The contents of the scratch register will be overwritten. 438 // The contents of the scratch register will be overwritten.
439 void IsInstanceJSObjectType(Register map, Register scratch, Label* fail); 439 void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
440 440
441 // FCmp is similar to integer cmp, but requires unsigned 441 // FCmp is similar to integer cmp, but requires unsigned
442 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). 442 // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
443 void FCmp(); 443 void FCmp();
444 444
445 void ClampUint8(Register reg); 445 void ClampUint8(Register reg);
446 446
447 void ClampDoubleToUint8(XMMRegister input_reg, 447 void ClampDoubleToUint8(XMMRegister input_reg,
448 XMMRegister scratch_reg, 448 XMMRegister scratch_reg,
449 Register result_reg); 449 Register result_reg);
450 450
451 451
452 // Smi tagging support. 452 // Smi tagging support.
453 void SmiTag(Register reg) { 453 void SmiTag(Register reg) {
454 STATIC_ASSERT(kSmiTag == 0); 454 STATIC_ASSERT(kSmiTag == 0);
455 STATIC_ASSERT(kSmiTagSize == 1); 455 STATIC_ASSERT(kSmiTagSize == 1);
456 add(reg, reg); 456 add(reg, reg);
457 } 457 }
458 void SmiUntag(Register reg) { 458 void SmiUntag(Register reg) {
459 sar(reg, kSmiTagSize); 459 sar(reg, kSmiTagSize);
460 } 460 }
461 461
462 // Modifies the register even if it does not contain a Smi! 462 // Modifies the register even if it does not contain a Smi!
463 void SmiUntag(Register reg, Label* is_smi) { 463 void SmiUntag(Register reg, Label* is_smi) {
464 STATIC_ASSERT(kSmiTagSize == 1); 464 STATIC_ASSERT(kSmiTagSize == 1);
465 sar(reg, kSmiTagSize); 465 sar(reg, kSmiTagSize);
466 STATIC_ASSERT(kSmiTag == 0); 466 STATIC_ASSERT(kSmiTag == 0);
467 j(not_carry, is_smi); 467 j(not_carry, is_smi);
468 } 468 }
469 469
470 void LoadUint32(XMMRegister dst, Register src, XMMRegister scratch); 470 void LoadUint32(XMMRegister dst, Register src, XMMRegister scratch);
471 471
472 // Jump the register contains a smi. 472 // Jump the register contains a smi.
473 inline void JumpIfSmi(Register value, 473 inline void JumpIfSmi(Register value,
474 Label* smi_label, 474 Label* smi_label,
475 Label::Distance distance = Label::kFar) { 475 Label::Distance distance = Label::kFar) {
476 test(value, Immediate(kSmiTagMask)); 476 test(value, Immediate(kSmiTagMask));
477 j(zero, smi_label, distance); 477 j(zero, smi_label, distance);
478 } 478 }
479 // Jump if the operand is a smi. 479 // Jump if the operand is a smi.
480 inline void JumpIfSmi(Operand value, 480 inline void JumpIfSmi(Operand value,
481 Label* smi_label, 481 Label* smi_label,
482 Label::Distance distance = Label::kFar) { 482 Label::Distance distance = Label::kFar) {
483 test(value, Immediate(kSmiTagMask)); 483 test(value, Immediate(kSmiTagMask));
484 j(zero, smi_label, distance); 484 j(zero, smi_label, distance);
485 } 485 }
486 // Jump if register contain a non-smi. 486 // Jump if register contain a non-smi.
487 inline void JumpIfNotSmi(Register value, 487 inline void JumpIfNotSmi(Register value,
488 Label* not_smi_label, 488 Label* not_smi_label,
489 Label::Distance distance = Label::kFar) { 489 Label::Distance distance = Label::kFar) {
490 test(value, Immediate(kSmiTagMask)); 490 test(value, Immediate(kSmiTagMask));
491 j(not_zero, not_smi_label, distance); 491 j(not_zero, not_smi_label, distance);
492 } 492 }
493 493
494 void LoadInstanceDescriptors(Register map, Register descriptors); 494 void LoadInstanceDescriptors(Register map, Register descriptors);
495 void EnumLength(Register dst, Register map); 495 void EnumLength(Register dst, Register map);
496 void NumberOfOwnDescriptors(Register dst, Register map);
496 497
497 template<typename Field> 498 template<typename Field>
498 void DecodeField(Register reg) { 499 void DecodeField(Register reg) {
499 static const int full_shift = Field::kShift + kSmiTagSize; 500 static const int shift = Field::kShift;
500 static const int low_mask = Field::kMask >> Field::kShift; 501 static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize;
501 sar(reg, full_shift); 502 sar(reg, shift);
502 and_(reg, Immediate(low_mask)); 503 and_(reg, Immediate(mask));
503 } 504 }
504 void LoadPowerOf2(XMMRegister dst, Register scratch, int power); 505 void LoadPowerOf2(XMMRegister dst, Register scratch, int power);
505 506
506 // Abort execution if argument is not a number. Used in debug code. 507 // Abort execution if argument is not a number. Used in debug code.
507 void AbortIfNotNumber(Register object); 508 void AbortIfNotNumber(Register object);
508 509
509 // Abort execution if argument is not a smi. Used in debug code. 510 // Abort execution if argument is not a smi. Used in debug code.
510 void AbortIfNotSmi(Register object); 511 void AbortIfNotSmi(Register object);
511 512
512 // Abort execution if argument is a smi. Used in debug code. 513 // Abort execution if argument is a smi. Used in debug code.
513 void AbortIfSmi(Register object); 514 void AbortIfSmi(Register object);
514 515
515 // Abort execution if argument is a string. Used in debug code. 516 // Abort execution if argument is a string. Used in debug code.
516 void AbortIfNotString(Register object); 517 void AbortIfNotString(Register object);
517 518
518 // --------------------------------------------------------------------------- 519 // ---------------------------------------------------------------------------
519 // Exception handling 520 // Exception handling
520 521
521 // Push a new try handler and link it into try handler chain. 522 // Push a new try handler and link it into try handler chain.
522 void PushTryHandler(StackHandler::Kind kind, int handler_index); 523 void PushTryHandler(StackHandler::Kind kind, int handler_index);
523 524
524 // Unlink the stack handler on top of the stack from the try handler chain. 525 // Unlink the stack handler on top of the stack from the try handler chain.
525 void PopTryHandler(); 526 void PopTryHandler();
526 527
527 // Throw to the top handler in the try hander chain. 528 // Throw to the top handler in the try hander chain.
528 void Throw(Register value); 529 void Throw(Register value);
529 530
530 // Throw past all JS frames to the top JS entry frame. 531 // Throw past all JS frames to the top JS entry frame.
531 void ThrowUncatchable(Register value); 532 void ThrowUncatchable(Register value);
532 533
533 // --------------------------------------------------------------------------- 534 // ---------------------------------------------------------------------------
534 // Inline caching support 535 // Inline caching support
535 536
536 // Generate code for checking access rights - used for security checks 537 // Generate code for checking access rights - used for security checks
537 // on access to global objects across environments. The holder register 538 // on access to global objects across environments. The holder register
538 // is left untouched, but the scratch register is clobbered. 539 // is left untouched, but the scratch register is clobbered.
539 void CheckAccessGlobalProxy(Register holder_reg, 540 void CheckAccessGlobalProxy(Register holder_reg,
540 Register scratch, 541 Register scratch,
541 Label* miss); 542 Label* miss);
542 543
543 void GetNumberHash(Register r0, Register scratch); 544 void GetNumberHash(Register r0, Register scratch);
544 545
545 void LoadFromNumberDictionary(Label* miss, 546 void LoadFromNumberDictionary(Label* miss,
546 Register elements, 547 Register elements,
547 Register key, 548 Register key,
548 Register r0, 549 Register r0,
549 Register r1, 550 Register r1,
550 Register r2, 551 Register r2,
551 Register result); 552 Register result);
552 553
553 554
554 // --------------------------------------------------------------------------- 555 // ---------------------------------------------------------------------------
555 // Allocation support 556 // Allocation support
556 557
557 // Allocate an object in new space. If the new space is exhausted control 558 // Allocate an object in new space. If the new space is exhausted control
558 // continues at the gc_required label. The allocated object is returned in 559 // continues at the gc_required label. The allocated object is returned in
559 // result and end of the new object is returned in result_end. The register 560 // result and end of the new object is returned in result_end. The register
560 // scratch can be passed as no_reg in which case an additional object 561 // scratch can be passed as no_reg in which case an additional object
561 // reference will be added to the reloc info. The returned pointers in result 562 // reference will be added to the reloc info. The returned pointers in result
562 // and result_end have not yet been tagged as heap objects. If 563 // and result_end have not yet been tagged as heap objects. If
563 // result_contains_top_on_entry is true the content of result is known to be 564 // result_contains_top_on_entry is true the content of result is known to be
564 // the allocation top on entry (could be result_end from a previous call to 565 // the allocation top on entry (could be result_end from a previous call to
565 // AllocateInNewSpace). If result_contains_top_on_entry is true scratch 566 // AllocateInNewSpace). If result_contains_top_on_entry is true scratch
566 // should be no_reg as it is never used. 567 // should be no_reg as it is never used.
567 void AllocateInNewSpace(int object_size, 568 void AllocateInNewSpace(int object_size,
568 Register result, 569 Register result,
569 Register result_end, 570 Register result_end,
570 Register scratch, 571 Register scratch,
571 Label* gc_required, 572 Label* gc_required,
572 AllocationFlags flags); 573 AllocationFlags flags);
573 574
574 void AllocateInNewSpace(int header_size, 575 void AllocateInNewSpace(int header_size,
575 ScaleFactor element_size, 576 ScaleFactor element_size,
576 Register element_count, 577 Register element_count,
577 Register result, 578 Register result,
578 Register result_end, 579 Register result_end,
579 Register scratch, 580 Register scratch,
580 Label* gc_required, 581 Label* gc_required,
581 AllocationFlags flags); 582 AllocationFlags flags);
582 583
583 void AllocateInNewSpace(Register object_size, 584 void AllocateInNewSpace(Register object_size,
584 Register result, 585 Register result,
585 Register result_end, 586 Register result_end,
586 Register scratch, 587 Register scratch,
587 Label* gc_required, 588 Label* gc_required,
588 AllocationFlags flags); 589 AllocationFlags flags);
589 590
590 // Undo allocation in new space. The object passed and objects allocated after 591 // Undo allocation in new space. The object passed and objects allocated after
591 // it will no longer be allocated. Make sure that no pointers are left to the 592 // it will no longer be allocated. Make sure that no pointers are left to the
592 // object(s) no longer allocated as they would be invalid when allocation is 593 // object(s) no longer allocated as they would be invalid when allocation is
593 // un-done. 594 // un-done.
594 void UndoAllocationInNewSpace(Register object); 595 void UndoAllocationInNewSpace(Register object);
595 596
596 // Allocate a heap number in new space with undefined value. The 597 // Allocate a heap number in new space with undefined value. The
597 // register scratch2 can be passed as no_reg; the others must be 598 // register scratch2 can be passed as no_reg; the others must be
598 // valid registers. Returns tagged pointer in result register, or 599 // valid registers. Returns tagged pointer in result register, or
599 // jumps to gc_required if new space is full. 600 // jumps to gc_required if new space is full.
600 void AllocateHeapNumber(Register result, 601 void AllocateHeapNumber(Register result,
601 Register scratch1, 602 Register scratch1,
602 Register scratch2, 603 Register scratch2,
603 Label* gc_required); 604 Label* gc_required);
604 605
605 // Allocate a sequential string. All the header fields of the string object 606 // Allocate a sequential string. All the header fields of the string object
606 // are initialized. 607 // are initialized.
607 void AllocateTwoByteString(Register result, 608 void AllocateTwoByteString(Register result,
608 Register length, 609 Register length,
609 Register scratch1, 610 Register scratch1,
610 Register scratch2, 611 Register scratch2,
611 Register scratch3, 612 Register scratch3,
612 Label* gc_required); 613 Label* gc_required);
613 void AllocateAsciiString(Register result, 614 void AllocateAsciiString(Register result,
614 Register length, 615 Register length,
615 Register scratch1, 616 Register scratch1,
616 Register scratch2, 617 Register scratch2,
617 Register scratch3, 618 Register scratch3,
618 Label* gc_required); 619 Label* gc_required);
619 void AllocateAsciiString(Register result, 620 void AllocateAsciiString(Register result,
620 int length, 621 int length,
621 Register scratch1, 622 Register scratch1,
622 Register scratch2, 623 Register scratch2,
623 Label* gc_required); 624 Label* gc_required);
624 625
625 // Allocate a raw cons string object. Only the map field of the result is 626 // Allocate a raw cons string object. Only the map field of the result is
626 // initialized. 627 // initialized.
627 void AllocateTwoByteConsString(Register result, 628 void AllocateTwoByteConsString(Register result,
628 Register scratch1, 629 Register scratch1,
629 Register scratch2, 630 Register scratch2,
630 Label* gc_required); 631 Label* gc_required);
631 void AllocateAsciiConsString(Register result, 632 void AllocateAsciiConsString(Register result,
632 Register scratch1, 633 Register scratch1,
633 Register scratch2, 634 Register scratch2,
634 Label* gc_required); 635 Label* gc_required);
635 636
636 // Allocate a raw sliced string object. Only the map field of the result is 637 // Allocate a raw sliced string object. Only the map field of the result is
637 // initialized. 638 // initialized.
638 void AllocateTwoByteSlicedString(Register result, 639 void AllocateTwoByteSlicedString(Register result,
639 Register scratch1, 640 Register scratch1,
640 Register scratch2, 641 Register scratch2,
641 Label* gc_required); 642 Label* gc_required);
642 void AllocateAsciiSlicedString(Register result, 643 void AllocateAsciiSlicedString(Register result,
643 Register scratch1, 644 Register scratch1,
644 Register scratch2, 645 Register scratch2,
645 Label* gc_required); 646 Label* gc_required);
646 647
647 // Copy memory, byte-by-byte, from source to destination. Not optimized for 648 // Copy memory, byte-by-byte, from source to destination. Not optimized for
648 // long or aligned copies. 649 // long or aligned copies.
649 // The contents of index and scratch are destroyed. 650 // The contents of index and scratch are destroyed.
650 void CopyBytes(Register source, 651 void CopyBytes(Register source,
651 Register destination, 652 Register destination,
652 Register length, 653 Register length,
653 Register scratch); 654 Register scratch);
654 655
655 // Initialize fields with filler values. Fields starting at |start_offset| 656 // Initialize fields with filler values. Fields starting at |start_offset|
656 // not including end_offset are overwritten with the value in |filler|. At 657 // not including end_offset are overwritten with the value in |filler|. At
657 // the end the loop, |start_offset| takes the value of |end_offset|. 658 // the end the loop, |start_offset| takes the value of |end_offset|.
658 void InitializeFieldsWithFiller(Register start_offset, 659 void InitializeFieldsWithFiller(Register start_offset,
659 Register end_offset, 660 Register end_offset,
660 Register filler); 661 Register filler);
661 662
662 // --------------------------------------------------------------------------- 663 // ---------------------------------------------------------------------------
663 // Support functions. 664 // Support functions.
664 665
665 // Check a boolean-bit of a Smi field. 666 // Check a boolean-bit of a Smi field.
666 void BooleanBitTest(Register object, int field_offset, int bit_index); 667 void BooleanBitTest(Register object, int field_offset, int bit_index);
667 668
668 // Check if result is zero and op is negative. 669 // Check if result is zero and op is negative.
669 void NegativeZeroTest(Register result, Register op, Label* then_label); 670 void NegativeZeroTest(Register result, Register op, Label* then_label);
670 671
671 // Check if result is zero and any of op1 and op2 are negative. 672 // Check if result is zero and any of op1 and op2 are negative.
672 // Register scratch is destroyed, and it must be different from op2. 673 // Register scratch is destroyed, and it must be different from op2.
673 void NegativeZeroTest(Register result, Register op1, Register op2, 674 void NegativeZeroTest(Register result, Register op1, Register op2,
674 Register scratch, Label* then_label); 675 Register scratch, Label* then_label);
675 676
676 // Try to get function prototype of a function and puts the value in 677 // Try to get function prototype of a function and puts the value in
677 // the result register. Checks that the function really is a 678 // the result register. Checks that the function really is a
678 // function and jumps to the miss label if the fast checks fail. The 679 // function and jumps to the miss label if the fast checks fail. The
679 // function register will be untouched; the other registers may be 680 // function register will be untouched; the other registers may be
680 // clobbered. 681 // clobbered.
681 void TryGetFunctionPrototype(Register function, 682 void TryGetFunctionPrototype(Register function,
682 Register result, 683 Register result,
683 Register scratch, 684 Register scratch,
684 Label* miss, 685 Label* miss,
685 bool miss_on_bound_function = false); 686 bool miss_on_bound_function = false);
686 687
687 // Generates code for reporting that an illegal operation has 688 // Generates code for reporting that an illegal operation has
688 // occurred. 689 // occurred.
689 void IllegalOperation(int num_arguments); 690 void IllegalOperation(int num_arguments);
690 691
691 // Picks out an array index from the hash field. 692 // Picks out an array index from the hash field.
692 // Register use: 693 // Register use:
693 // hash - holds the index's hash. Clobbered. 694 // hash - holds the index's hash. Clobbered.
694 // index - holds the overwritten index on exit. 695 // index - holds the overwritten index on exit.
695 void IndexFromHash(Register hash, Register index); 696 void IndexFromHash(Register hash, Register index);
696 697
697 // --------------------------------------------------------------------------- 698 // ---------------------------------------------------------------------------
698 // Runtime calls 699 // Runtime calls
699 700
700 // Call a code stub. Generate the code if necessary. 701 // Call a code stub. Generate the code if necessary.
701 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); 702 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None());
702 703
703 // Tail call a code stub (jump). Generate the code if necessary. 704 // Tail call a code stub (jump). Generate the code if necessary.
704 void TailCallStub(CodeStub* stub); 705 void TailCallStub(CodeStub* stub);
705 706
706 // Return from a code stub after popping its arguments. 707 // Return from a code stub after popping its arguments.
707 void StubReturn(int argc); 708 void StubReturn(int argc);
708 709
709 // Call a runtime routine. 710 // Call a runtime routine.
710 void CallRuntime(const Runtime::Function* f, int num_arguments); 711 void CallRuntime(const Runtime::Function* f, int num_arguments);
711 void CallRuntimeSaveDoubles(Runtime::FunctionId id); 712 void CallRuntimeSaveDoubles(Runtime::FunctionId id);
712 713
713 // Convenience function: Same as above, but takes the fid instead. 714 // Convenience function: Same as above, but takes the fid instead.
714 void CallRuntime(Runtime::FunctionId id, int num_arguments); 715 void CallRuntime(Runtime::FunctionId id, int num_arguments);
715 716
716 // Convenience function: call an external reference. 717 // Convenience function: call an external reference.
717 void CallExternalReference(ExternalReference ref, int num_arguments); 718 void CallExternalReference(ExternalReference ref, int num_arguments);
718 719
719 // Tail call of a runtime routine (jump). 720 // Tail call of a runtime routine (jump).
720 // Like JumpToExternalReference, but also takes care of passing the number 721 // Like JumpToExternalReference, but also takes care of passing the number
721 // of parameters. 722 // of parameters.
722 void TailCallExternalReference(const ExternalReference& ext, 723 void TailCallExternalReference(const ExternalReference& ext,
723 int num_arguments, 724 int num_arguments,
724 int result_size); 725 int result_size);
725 726
726 // Convenience function: tail call a runtime routine (jump). 727 // Convenience function: tail call a runtime routine (jump).
727 void TailCallRuntime(Runtime::FunctionId fid, 728 void TailCallRuntime(Runtime::FunctionId fid,
728 int num_arguments, 729 int num_arguments,
729 int result_size); 730 int result_size);
730 731
731 // Before calling a C-function from generated code, align arguments on stack. 732 // Before calling a C-function from generated code, align arguments on stack.
732 // After aligning the frame, arguments must be stored in esp[0], esp[4], 733 // After aligning the frame, arguments must be stored in esp[0], esp[4],
733 // etc., not pushed. The argument count assumes all arguments are word sized. 734 // etc., not pushed. The argument count assumes all arguments are word sized.
734 // Some compilers/platforms require the stack to be aligned when calling 735 // Some compilers/platforms require the stack to be aligned when calling
735 // C++ code. 736 // C++ code.
736 // Needs a scratch register to do some arithmetic. This register will be 737 // Needs a scratch register to do some arithmetic. This register will be
737 // trashed. 738 // trashed.
738 void PrepareCallCFunction(int num_arguments, Register scratch); 739 void PrepareCallCFunction(int num_arguments, Register scratch);
739 740
740 // Calls a C function and cleans up the space for arguments allocated 741 // Calls a C function and cleans up the space for arguments allocated
741 // by PrepareCallCFunction. The called function is not allowed to trigger a 742 // by PrepareCallCFunction. The called function is not allowed to trigger a
742 // garbage collection, since that might move the code and invalidate the 743 // garbage collection, since that might move the code and invalidate the
743 // return address (unless this is somehow accounted for by the called 744 // return address (unless this is somehow accounted for by the called
744 // function). 745 // function).
745 void CallCFunction(ExternalReference function, int num_arguments); 746 void CallCFunction(ExternalReference function, int num_arguments);
746 void CallCFunction(Register function, int num_arguments); 747 void CallCFunction(Register function, int num_arguments);
747 748
748 // Prepares stack to put arguments (aligns and so on). Reserves 749 // Prepares stack to put arguments (aligns and so on). Reserves
749 // space for return value if needed (assumes the return value is a handle). 750 // space for return value if needed (assumes the return value is a handle).
750 // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1) 751 // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
751 // etc. Saves context (esi). If space was reserved for return value then 752 // etc. Saves context (esi). If space was reserved for return value then
752 // stores the pointer to the reserved slot into esi. 753 // stores the pointer to the reserved slot into esi.
753 void PrepareCallApiFunction(int argc); 754 void PrepareCallApiFunction(int argc);
754 755
755 // Calls an API function. Allocates HandleScope, extracts returned value 756 // Calls an API function. Allocates HandleScope, extracts returned value
756 // from handle and propagates exceptions. Clobbers ebx, edi and 757 // from handle and propagates exceptions. Clobbers ebx, edi and
757 // caller-save registers. Restores context. On return removes 758 // caller-save registers. Restores context. On return removes
758 // stack_space * kPointerSize (GCed). 759 // stack_space * kPointerSize (GCed).
759 void CallApiFunctionAndReturn(Address function_address, int stack_space); 760 void CallApiFunctionAndReturn(Address function_address, int stack_space);
760 761
761 // Jump to a runtime routine. 762 // Jump to a runtime routine.
762 void JumpToExternalReference(const ExternalReference& ext); 763 void JumpToExternalReference(const ExternalReference& ext);
763 764
764 // --------------------------------------------------------------------------- 765 // ---------------------------------------------------------------------------
765 // Utilities 766 // Utilities
766 767
767 void Ret(); 768 void Ret();
768 769
769 // Return and drop arguments from stack, where the number of arguments 770 // Return and drop arguments from stack, where the number of arguments
770 // may be bigger than 2^16 - 1. Requires a scratch register. 771 // may be bigger than 2^16 - 1. Requires a scratch register.
771 void Ret(int bytes_dropped, Register scratch); 772 void Ret(int bytes_dropped, Register scratch);
772 773
773 // Emit code to discard a non-negative number of pointer-sized elements 774 // Emit code to discard a non-negative number of pointer-sized elements
774 // from the stack, clobbering only the esp register. 775 // from the stack, clobbering only the esp register.
775 void Drop(int element_count); 776 void Drop(int element_count);
776 777
777 void Call(Label* target) { call(target); } 778 void Call(Label* target) { call(target); }
778 779
779 // Emit call to the code we are currently generating. 780 // Emit call to the code we are currently generating.
780 void CallSelf() { 781 void CallSelf() {
781 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); 782 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
782 call(self, RelocInfo::CODE_TARGET); 783 call(self, RelocInfo::CODE_TARGET);
783 } 784 }
784 785
785 // Move if the registers are not identical. 786 // Move if the registers are not identical.
786 void Move(Register target, Register source); 787 void Move(Register target, Register source);
787 788
788 // Push a handle value. 789 // Push a handle value.
789 void Push(Handle<Object> handle) { push(Immediate(handle)); } 790 void Push(Handle<Object> handle) { push(Immediate(handle)); }
790 791
791 Handle<Object> CodeObject() { 792 Handle<Object> CodeObject() {
792 ASSERT(!code_object_.is_null()); 793 ASSERT(!code_object_.is_null());
793 return code_object_; 794 return code_object_;
794 } 795 }
795 796
796 797
797 // --------------------------------------------------------------------------- 798 // ---------------------------------------------------------------------------
798 // StatsCounter support 799 // StatsCounter support
799 800
800 void SetCounter(StatsCounter* counter, int value); 801 void SetCounter(StatsCounter* counter, int value);
801 void IncrementCounter(StatsCounter* counter, int value); 802 void IncrementCounter(StatsCounter* counter, int value);
802 void DecrementCounter(StatsCounter* counter, int value); 803 void DecrementCounter(StatsCounter* counter, int value);
803 void IncrementCounter(Condition cc, StatsCounter* counter, int value); 804 void IncrementCounter(Condition cc, StatsCounter* counter, int value);
804 void DecrementCounter(Condition cc, StatsCounter* counter, int value); 805 void DecrementCounter(Condition cc, StatsCounter* counter, int value);
805 806
806 807
807 // --------------------------------------------------------------------------- 808 // ---------------------------------------------------------------------------
808 // Debugging 809 // Debugging
809 810
810 // Calls Abort(msg) if the condition cc is not satisfied. 811 // Calls Abort(msg) if the condition cc is not satisfied.
811 // Use --debug_code to enable. 812 // Use --debug_code to enable.
812 void Assert(Condition cc, const char* msg); 813 void Assert(Condition cc, const char* msg);
813 814
814 void AssertFastElements(Register elements); 815 void AssertFastElements(Register elements);
815 816
816 // Like Assert(), but always enabled. 817 // Like Assert(), but always enabled.
817 void Check(Condition cc, const char* msg); 818 void Check(Condition cc, const char* msg);
818 819
819 // Print a message to stdout and abort execution. 820 // Print a message to stdout and abort execution.
820 void Abort(const char* msg); 821 void Abort(const char* msg);
821 822
822 // Check that the stack is aligned. 823 // Check that the stack is aligned.
823 void CheckStackAlignment(); 824 void CheckStackAlignment();
824 825
825 // Verify restrictions about code generated in stubs. 826 // Verify restrictions about code generated in stubs.
826 void set_generating_stub(bool value) { generating_stub_ = value; } 827 void set_generating_stub(bool value) { generating_stub_ = value; }
827 bool generating_stub() { return generating_stub_; } 828 bool generating_stub() { return generating_stub_; }
828 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 829 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
829 bool allow_stub_calls() { return allow_stub_calls_; } 830 bool allow_stub_calls() { return allow_stub_calls_; }
830 void set_has_frame(bool value) { has_frame_ = value; } 831 void set_has_frame(bool value) { has_frame_ = value; }
831 bool has_frame() { return has_frame_; } 832 bool has_frame() { return has_frame_; }
832 inline bool AllowThisStubCall(CodeStub* stub); 833 inline bool AllowThisStubCall(CodeStub* stub);
833 834
834 // --------------------------------------------------------------------------- 835 // ---------------------------------------------------------------------------
835 // String utilities. 836 // String utilities.
836 837
837 // Check whether the instance type represents a flat ASCII string. Jump to the 838 // Check whether the instance type represents a flat ASCII string. Jump to the
838 // label if not. If the instance type can be scratched specify same register 839 // label if not. If the instance type can be scratched specify same register
839 // for both instance type and scratch. 840 // for both instance type and scratch.
840 void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type, 841 void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type,
841 Register scratch, 842 Register scratch,
842 Label* on_not_flat_ascii_string); 843 Label* on_not_flat_ascii_string);
843 844
844 // Checks if both objects are sequential ASCII strings, and jumps to label 845 // Checks if both objects are sequential ASCII strings, and jumps to label
845 // if either is not. 846 // if either is not.
846 void JumpIfNotBothSequentialAsciiStrings(Register object1, 847 void JumpIfNotBothSequentialAsciiStrings(Register object1,
847 Register object2, 848 Register object2,
848 Register scratch1, 849 Register scratch1,
849 Register scratch2, 850 Register scratch2,
850 Label* on_not_flat_ascii_strings); 851 Label* on_not_flat_ascii_strings);
851 852
852 static int SafepointRegisterStackIndex(Register reg) { 853 static int SafepointRegisterStackIndex(Register reg) {
853 return SafepointRegisterStackIndex(reg.code()); 854 return SafepointRegisterStackIndex(reg.code());
854 } 855 }
855 856
856 // Activation support. 857 // Activation support.
857 void EnterFrame(StackFrame::Type type); 858 void EnterFrame(StackFrame::Type type);
858 void LeaveFrame(StackFrame::Type type); 859 void LeaveFrame(StackFrame::Type type);
859 860
860 // Expects object in eax and returns map with validated enum cache 861 // Expects object in eax and returns map with validated enum cache
861 // in eax. Assumes that any other register can be used as a scratch. 862 // in eax. Assumes that any other register can be used as a scratch.
862 void CheckEnumCache(Label* call_runtime); 863 void CheckEnumCache(Label* call_runtime);
863 864
864 private: 865 private:
865 bool generating_stub_; 866 bool generating_stub_;
866 bool allow_stub_calls_; 867 bool allow_stub_calls_;
867 bool has_frame_; 868 bool has_frame_;
868 // This handle will be patched with the code object on installation. 869 // This handle will be patched with the code object on installation.
869 Handle<Object> code_object_; 870 Handle<Object> code_object_;
870 871
871 // Helper functions for generating invokes. 872 // Helper functions for generating invokes.
872 void InvokePrologue(const ParameterCount& expected, 873 void InvokePrologue(const ParameterCount& expected,
873 const ParameterCount& actual, 874 const ParameterCount& actual,
874 Handle<Code> code_constant, 875 Handle<Code> code_constant,
875 const Operand& code_operand, 876 const Operand& code_operand,
876 Label* done, 877 Label* done,
877 bool* definitely_mismatches, 878 bool* definitely_mismatches,
878 InvokeFlag flag, 879 InvokeFlag flag,
879 Label::Distance done_distance, 880 Label::Distance done_distance,
880 const CallWrapper& call_wrapper = NullCallWrapper(), 881 const CallWrapper& call_wrapper = NullCallWrapper(),
881 CallKind call_kind = CALL_AS_METHOD); 882 CallKind call_kind = CALL_AS_METHOD);
882 883
883 void EnterExitFramePrologue(); 884 void EnterExitFramePrologue();
884 void EnterExitFrameEpilogue(int argc, bool save_doubles); 885 void EnterExitFrameEpilogue(int argc, bool save_doubles);
885 886
886 void LeaveExitFrameEpilogue(); 887 void LeaveExitFrameEpilogue();
887 888
888 // Allocation support helpers. 889 // Allocation support helpers.
889 void LoadAllocationTopHelper(Register result, 890 void LoadAllocationTopHelper(Register result,
890 Register scratch, 891 Register scratch,
891 AllocationFlags flags); 892 AllocationFlags flags);
892 void UpdateAllocationTopHelper(Register result_end, Register scratch); 893 void UpdateAllocationTopHelper(Register result_end, Register scratch);
893 894
894 // Helper for PopHandleScope. Allowed to perform a GC and returns 895 // Helper for PopHandleScope. Allowed to perform a GC and returns
895 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and 896 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
896 // possibly returns a failure object indicating an allocation failure. 897 // possibly returns a failure object indicating an allocation failure.
897 MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved, 898 MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved,
898 Register scratch, 899 Register scratch,
899 bool gc_allowed); 900 bool gc_allowed);
900 901
901 // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. 902 // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
902 void InNewSpace(Register object, 903 void InNewSpace(Register object,
903 Register scratch, 904 Register scratch,
904 Condition cc, 905 Condition cc,
905 Label* condition_met, 906 Label* condition_met,
906 Label::Distance condition_met_distance = Label::kFar); 907 Label::Distance condition_met_distance = Label::kFar);
907 908
908 // Helper for finding the mark bits for an address. Afterwards, the 909 // Helper for finding the mark bits for an address. Afterwards, the
909 // bitmap register points at the word with the mark bits and the mask 910 // bitmap register points at the word with the mark bits and the mask
910 // the position of the first bit. Uses ecx as scratch and leaves addr_reg 911 // the position of the first bit. Uses ecx as scratch and leaves addr_reg
911 // unchanged. 912 // unchanged.
912 inline void GetMarkBits(Register addr_reg, 913 inline void GetMarkBits(Register addr_reg,
913 Register bitmap_reg, 914 Register bitmap_reg,
914 Register mask_reg); 915 Register mask_reg);
915 916
916 // Helper for throwing exceptions. Compute a handler address and jump to 917 // Helper for throwing exceptions. Compute a handler address and jump to
917 // it. See the implementation for register usage. 918 // it. See the implementation for register usage.
918 void JumpToHandlerEntry(); 919 void JumpToHandlerEntry();
919 920
920 // Compute memory operands for safepoint stack slots. 921 // Compute memory operands for safepoint stack slots.
921 Operand SafepointRegisterSlot(Register reg); 922 Operand SafepointRegisterSlot(Register reg);
922 static int SafepointRegisterStackIndex(int reg_code); 923 static int SafepointRegisterStackIndex(int reg_code);
923 924
924 // Needs access to SafepointRegisterStackIndex for optimized frame 925 // Needs access to SafepointRegisterStackIndex for optimized frame
925 // traversal. 926 // traversal.
926 friend class OptimizedFrame; 927 friend class OptimizedFrame;
927 }; 928 };
928 929
929 930
930 // The code patcher is used to patch (typically) small parts of code e.g. for 931 // The code patcher is used to patch (typically) small parts of code e.g. for
931 // debugging and other types of instrumentation. When using the code patcher 932 // debugging and other types of instrumentation. When using the code patcher
932 // the exact number of bytes specified must be emitted. Is not legal to emit 933 // the exact number of bytes specified must be emitted. Is not legal to emit
933 // relocation information. If any of these constraints are violated it causes 934 // relocation information. If any of these constraints are violated it causes
934 // an assertion. 935 // an assertion.
935 class CodePatcher { 936 class CodePatcher {
936 public: 937 public:
937 CodePatcher(byte* address, int size); 938 CodePatcher(byte* address, int size);
938 virtual ~CodePatcher(); 939 virtual ~CodePatcher();
939 940
940 // Macro assembler to emit code. 941 // Macro assembler to emit code.
941 MacroAssembler* masm() { return &masm_; } 942 MacroAssembler* masm() { return &masm_; }
942 943
943 private: 944 private:
944 byte* address_; // The address of the code being patched. 945 byte* address_; // The address of the code being patched.
945 int size_; // Number of bytes of the expected patch size. 946 int size_; // Number of bytes of the expected patch size.
946 MacroAssembler masm_; // Macro assembler used to generate the code. 947 MacroAssembler masm_; // Macro assembler used to generate the code.
947 }; 948 };
948 949
949 950
950 // ----------------------------------------------------------------------------- 951 // -----------------------------------------------------------------------------
951 // Static helper functions. 952 // Static helper functions.
952 953
953 // Generate an Operand for loading a field from an object. 954 // Generate an Operand for loading a field from an object.
954 inline Operand FieldOperand(Register object, int offset) { 955 inline Operand FieldOperand(Register object, int offset) {
955 return Operand(object, offset - kHeapObjectTag); 956 return Operand(object, offset - kHeapObjectTag);
956 } 957 }
957 958
958 959
959 // Generate an Operand for loading an indexed field from an object. 960 // Generate an Operand for loading an indexed field from an object.
960 inline Operand FieldOperand(Register object, 961 inline Operand FieldOperand(Register object,
961 Register index, 962 Register index,
962 ScaleFactor scale, 963 ScaleFactor scale,
963 int offset) { 964 int offset) {
964 return Operand(object, index, scale, offset - kHeapObjectTag); 965 return Operand(object, index, scale, offset - kHeapObjectTag);
965 } 966 }
966 967
967 968
968 inline Operand ContextOperand(Register context, int index) { 969 inline Operand ContextOperand(Register context, int index) {
969 return Operand(context, Context::SlotOffset(index)); 970 return Operand(context, Context::SlotOffset(index));
970 } 971 }
971 972
972 973
973 inline Operand GlobalObjectOperand() { 974 inline Operand GlobalObjectOperand() {
974 return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX); 975 return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX);
975 } 976 }
976 977
977 978
978 // Generates an Operand for saving parameters after PrepareCallApiFunction. 979 // Generates an Operand for saving parameters after PrepareCallApiFunction.
979 Operand ApiParameterOperand(int index); 980 Operand ApiParameterOperand(int index);
980 981
981 982
982 #ifdef GENERATED_CODE_COVERAGE 983 #ifdef GENERATED_CODE_COVERAGE
983 extern void LogGeneratedCodeCoverage(const char* file_line); 984 extern void LogGeneratedCodeCoverage(const char* file_line);
984 #define CODE_COVERAGE_STRINGIFY(x) #x 985 #define CODE_COVERAGE_STRINGIFY(x) #x
985 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 986 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
986 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 987 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
987 #define ACCESS_MASM(masm) { \ 988 #define ACCESS_MASM(masm) { \
988 byte* ia32_coverage_function = \ 989 byte* ia32_coverage_function = \
989 reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \ 990 reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
990 masm->pushfd(); \ 991 masm->pushfd(); \
991 masm->pushad(); \ 992 masm->pushad(); \
992 masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ 993 masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \
993 masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \ 994 masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \
994 masm->pop(eax); \ 995 masm->pop(eax); \
995 masm->popad(); \ 996 masm->popad(); \
996 masm->popfd(); \ 997 masm->popfd(); \
997 } \ 998 } \
998 masm-> 999 masm->
999 #else 1000 #else
1000 #define ACCESS_MASM(masm) masm-> 1001 #define ACCESS_MASM(masm) masm->
1001 #endif 1002 #endif
1002 1003
1003 1004
1004 } } // namespace v8::internal 1005 } } // namespace v8::internal
1005 1006
1006 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ 1007 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_
Powered by Google Project Hosting