OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 5 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
6 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 6 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
7 | 7 |
8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/frames.h" | 10 #include "src/frames.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 // distinguish memory operands from other operands on ia32. | 34 // distinguish memory operands from other operands on ia32. |
35 typedef Operand MemOperand; | 35 typedef Operand MemOperand; |
36 | 36 |
37 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; | 37 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; |
38 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; | 38 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; |
39 enum PointersToHereCheck { | 39 enum PointersToHereCheck { |
40 kPointersToHereMaybeInteresting, | 40 kPointersToHereMaybeInteresting, |
41 kPointersToHereAreAlwaysInteresting | 41 kPointersToHereAreAlwaysInteresting |
42 }; | 42 }; |
43 | 43 |
44 | 44 enum RegisterValueType { REGISTER_VALUE_IS_SMI, REGISTER_VALUE_IS_INT32 }; |
45 enum RegisterValueType { | |
46 REGISTER_VALUE_IS_SMI, | |
47 REGISTER_VALUE_IS_INT32 | |
48 }; | |
49 | |
50 | 45 |
51 #ifdef DEBUG | 46 #ifdef DEBUG |
52 bool AreAliased(Register reg1, | 47 bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg, |
53 Register reg2, | 48 Register reg4 = no_reg, Register reg5 = no_reg, |
54 Register reg3 = no_reg, | 49 Register reg6 = no_reg, Register reg7 = no_reg, |
55 Register reg4 = no_reg, | |
56 Register reg5 = no_reg, | |
57 Register reg6 = no_reg, | |
58 Register reg7 = no_reg, | |
59 Register reg8 = no_reg); | 50 Register reg8 = no_reg); |
60 #endif | 51 #endif |
61 | 52 |
62 | |
63 // MacroAssembler implements a collection of frequently used macros. | 53 // MacroAssembler implements a collection of frequently used macros. |
64 class MacroAssembler: public Assembler { | 54 class MacroAssembler: public Assembler { |
65 public: | 55 public: |
66 MacroAssembler(Isolate* isolate, void* buffer, int size, | 56 MacroAssembler(Isolate* isolate, void* buffer, int size, |
67 CodeObjectRequired create_code_object); | 57 CodeObjectRequired create_code_object); |
68 | 58 |
69 void Load(Register dst, const Operand& src, Representation r); | 59 void Load(Register dst, const Operand& src, Representation r); |
70 void Store(Register src, const Operand& dst, Representation r); | 60 void Store(Register src, const Operand& dst, Representation r); |
71 | 61 |
72 // Load a register with a long value as efficiently as possible. | 62 // Load a register with a long value as efficiently as possible. |
(...skipping 26 matching lines...) Expand all Loading... |
99 // Compare the object in a register to a value and jump if they are not equal. | 89 // Compare the object in a register to a value and jump if they are not equal. |
100 void JumpIfNotRoot(Register with, Heap::RootListIndex index, | 90 void JumpIfNotRoot(Register with, Heap::RootListIndex index, |
101 Label* if_not_equal, | 91 Label* if_not_equal, |
102 Label::Distance if_not_equal_distance = Label::kNear) { | 92 Label::Distance if_not_equal_distance = Label::kNear) { |
103 CompareRoot(with, index); | 93 CompareRoot(with, index); |
104 j(not_equal, if_not_equal, if_not_equal_distance); | 94 j(not_equal, if_not_equal, if_not_equal_distance); |
105 } | 95 } |
106 | 96 |
107 // --------------------------------------------------------------------------- | 97 // --------------------------------------------------------------------------- |
108 // GC Support | 98 // GC Support |
109 enum RememberedSetFinalAction { | 99 enum RememberedSetFinalAction { kReturnAtEnd, kFallThroughAtEnd }; |
110 kReturnAtEnd, | |
111 kFallThroughAtEnd | |
112 }; | |
113 | 100 |
114 // Record in the remembered set the fact that we have a pointer to new space | 101 // Record in the remembered set the fact that we have a pointer to new space |
115 // at the address pointed to by the addr register. Only works if addr is not | 102 // at the address pointed to by the addr register. Only works if addr is not |
116 // in new space. | 103 // in new space. |
117 void RememberedSetHelper(Register object, // Used for debug code. | 104 void RememberedSetHelper(Register object, // Used for debug code. |
118 Register addr, | 105 Register addr, Register scratch, |
119 Register scratch, | |
120 SaveFPRegsMode save_fp, | 106 SaveFPRegsMode save_fp, |
121 RememberedSetFinalAction and_then); | 107 RememberedSetFinalAction and_then); |
122 | 108 |
123 void CheckPageFlag(Register object, | 109 void CheckPageFlag(Register object, Register scratch, int mask, Condition cc, |
124 Register scratch, | |
125 int mask, | |
126 Condition cc, | |
127 Label* condition_met, | 110 Label* condition_met, |
128 Label::Distance condition_met_distance = Label::kFar); | 111 Label::Distance condition_met_distance = Label::kFar); |
129 | 112 |
130 void CheckPageFlagForMap( | 113 void CheckPageFlagForMap( |
131 Handle<Map> map, | 114 Handle<Map> map, int mask, Condition cc, Label* condition_met, |
132 int mask, | |
133 Condition cc, | |
134 Label* condition_met, | |
135 Label::Distance condition_met_distance = Label::kFar); | 115 Label::Distance condition_met_distance = Label::kFar); |
136 | 116 |
137 // Check if object is in new space. Jumps if the object is not in new space. | 117 // Check if object is in new space. Jumps if the object is not in new space. |
138 // The register scratch can be object itself, but scratch will be clobbered. | 118 // The register scratch can be object itself, but scratch will be clobbered. |
139 void JumpIfNotInNewSpace(Register object, | 119 void JumpIfNotInNewSpace(Register object, Register scratch, Label* branch, |
140 Register scratch, | |
141 Label* branch, | |
142 Label::Distance distance = Label::kFar) { | 120 Label::Distance distance = Label::kFar) { |
143 InNewSpace(object, scratch, zero, branch, distance); | 121 InNewSpace(object, scratch, zero, branch, distance); |
144 } | 122 } |
145 | 123 |
146 // Check if object is in new space. Jumps if the object is in new space. | 124 // Check if object is in new space. Jumps if the object is in new space. |
147 // The register scratch can be object itself, but it will be clobbered. | 125 // The register scratch can be object itself, but it will be clobbered. |
148 void JumpIfInNewSpace(Register object, | 126 void JumpIfInNewSpace(Register object, Register scratch, Label* branch, |
149 Register scratch, | |
150 Label* branch, | |
151 Label::Distance distance = Label::kFar) { | 127 Label::Distance distance = Label::kFar) { |
152 InNewSpace(object, scratch, not_zero, branch, distance); | 128 InNewSpace(object, scratch, not_zero, branch, distance); |
153 } | 129 } |
154 | 130 |
155 // Check if an object has a given incremental marking color. Also uses ecx! | 131 // Check if an object has a given incremental marking color. Also uses ecx! |
156 void HasColor(Register object, | 132 void HasColor(Register object, Register scratch0, Register scratch1, |
157 Register scratch0, | 133 Label* has_color, Label::Distance has_color_distance, |
158 Register scratch1, | 134 int first_bit, int second_bit); |
159 Label* has_color, | |
160 Label::Distance has_color_distance, | |
161 int first_bit, | |
162 int second_bit); | |
163 | 135 |
164 void JumpIfBlack(Register object, | 136 void JumpIfBlack(Register object, Register scratch0, Register scratch1, |
165 Register scratch0, | |
166 Register scratch1, | |
167 Label* on_black, | 137 Label* on_black, |
168 Label::Distance on_black_distance = Label::kFar); | 138 Label::Distance on_black_distance = Label::kFar); |
169 | 139 |
170 // Checks the color of an object. If the object is already grey or black | 140 // Checks the color of an object. If the object is already grey or black |
171 // then we just fall through, since it is already live. If it is white and | 141 // then we just fall through, since it is already live. If it is white and |
172 // we can determine that it doesn't need to be scanned, then we just mark it | 142 // we can determine that it doesn't need to be scanned, then we just mark it |
173 // black and fall through. For the rest we jump to the label so the | 143 // black and fall through. For the rest we jump to the label so the |
174 // incremental marker can fix its assumptions. | 144 // incremental marker can fix its assumptions. |
175 void EnsureNotWhite(Register object, | 145 void EnsureNotWhite(Register object, Register scratch1, Register scratch2, |
176 Register scratch1, | |
177 Register scratch2, | |
178 Label* object_is_white_and_not_data, | 146 Label* object_is_white_and_not_data, |
179 Label::Distance distance); | 147 Label::Distance distance); |
180 | 148 |
181 // Notify the garbage collector that we wrote a pointer into an object. | 149 // Notify the garbage collector that we wrote a pointer into an object. |
182 // |object| is the object being stored into, |value| is the object being | 150 // |object| is the object being stored into, |value| is the object being |
183 // stored. value and scratch registers are clobbered by the operation. | 151 // stored. value and scratch registers are clobbered by the operation. |
184 // The offset is the offset from the start of the object, not the offset from | 152 // The offset is the offset from the start of the object, not the offset from |
185 // the tagged HeapObject pointer. For use with FieldOperand(reg, off). | 153 // the tagged HeapObject pointer. For use with FieldOperand(reg, off). |
186 void RecordWriteField( | 154 void RecordWriteField( |
187 Register object, | 155 Register object, int offset, Register value, Register scratch, |
188 int offset, | |
189 Register value, | |
190 Register scratch, | |
191 SaveFPRegsMode save_fp, | 156 SaveFPRegsMode save_fp, |
192 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | 157 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
193 SmiCheck smi_check = INLINE_SMI_CHECK, | 158 SmiCheck smi_check = INLINE_SMI_CHECK, |
194 PointersToHereCheck pointers_to_here_check_for_value = | 159 PointersToHereCheck pointers_to_here_check_for_value = |
195 kPointersToHereMaybeInteresting); | 160 kPointersToHereMaybeInteresting); |
196 | 161 |
197 // As above, but the offset has the tag presubtracted. For use with | 162 // As above, but the offset has the tag presubtracted. For use with |
198 // Operand(reg, off). | 163 // Operand(reg, off). |
199 void RecordWriteContextSlot( | 164 void RecordWriteContextSlot( |
200 Register context, | 165 Register context, int offset, Register value, Register scratch, |
201 int offset, | |
202 Register value, | |
203 Register scratch, | |
204 SaveFPRegsMode save_fp, | 166 SaveFPRegsMode save_fp, |
205 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | 167 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
206 SmiCheck smi_check = INLINE_SMI_CHECK, | 168 SmiCheck smi_check = INLINE_SMI_CHECK, |
207 PointersToHereCheck pointers_to_here_check_for_value = | 169 PointersToHereCheck pointers_to_here_check_for_value = |
208 kPointersToHereMaybeInteresting) { | 170 kPointersToHereMaybeInteresting) { |
209 RecordWriteField(context, | 171 RecordWriteField(context, offset + kHeapObjectTag, value, scratch, save_fp, |
210 offset + kHeapObjectTag, | 172 remembered_set_action, smi_check, |
211 value, | |
212 scratch, | |
213 save_fp, | |
214 remembered_set_action, | |
215 smi_check, | |
216 pointers_to_here_check_for_value); | 173 pointers_to_here_check_for_value); |
217 } | 174 } |
218 | 175 |
219 // Notify the garbage collector that we wrote a pointer into a fixed array. | 176 // Notify the garbage collector that we wrote a pointer into a fixed array. |
220 // |array| is the array being stored into, |value| is the | 177 // |array| is the array being stored into, |value| is the |
221 // object being stored. |index| is the array index represented as a | 178 // object being stored. |index| is the array index represented as a |
222 // Smi. All registers are clobbered by the operation RecordWriteArray | 179 // Smi. All registers are clobbered by the operation RecordWriteArray |
223 // filters out smis so it does not update the write barrier if the | 180 // filters out smis so it does not update the write barrier if the |
224 // value is a smi. | 181 // value is a smi. |
225 void RecordWriteArray( | 182 void RecordWriteArray( |
226 Register array, | 183 Register array, Register value, Register index, SaveFPRegsMode save_fp, |
227 Register value, | |
228 Register index, | |
229 SaveFPRegsMode save_fp, | |
230 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | 184 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
231 SmiCheck smi_check = INLINE_SMI_CHECK, | 185 SmiCheck smi_check = INLINE_SMI_CHECK, |
232 PointersToHereCheck pointers_to_here_check_for_value = | 186 PointersToHereCheck pointers_to_here_check_for_value = |
233 kPointersToHereMaybeInteresting); | 187 kPointersToHereMaybeInteresting); |
234 | 188 |
235 // For page containing |object| mark region covering |address| | 189 // For page containing |object| mark region covering |address| |
236 // dirty. |object| is the object being stored into, |value| is the | 190 // dirty. |object| is the object being stored into, |value| is the |
237 // object being stored. The address and value registers are clobbered by the | 191 // object being stored. The address and value registers are clobbered by the |
238 // operation. RecordWrite filters out smis so it does not update the | 192 // operation. RecordWrite filters out smis so it does not update the |
239 // write barrier if the value is a smi. | 193 // write barrier if the value is a smi. |
240 void RecordWrite( | 194 void RecordWrite( |
241 Register object, | 195 Register object, Register address, Register value, SaveFPRegsMode save_fp, |
242 Register address, | |
243 Register value, | |
244 SaveFPRegsMode save_fp, | |
245 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | 196 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
246 SmiCheck smi_check = INLINE_SMI_CHECK, | 197 SmiCheck smi_check = INLINE_SMI_CHECK, |
247 PointersToHereCheck pointers_to_here_check_for_value = | 198 PointersToHereCheck pointers_to_here_check_for_value = |
248 kPointersToHereMaybeInteresting); | 199 kPointersToHereMaybeInteresting); |
249 | 200 |
250 // For page containing |object| mark the region covering the object's map | 201 // For page containing |object| mark the region covering the object's map |
251 // dirty. |object| is the object being stored into, |map| is the Map object | 202 // dirty. |object| is the object being stored into, |map| is the Map object |
252 // that was stored. | 203 // that was stored. |
253 void RecordWriteForMap( | 204 void RecordWriteForMap(Register object, Handle<Map> map, Register scratch1, |
254 Register object, | 205 Register scratch2, SaveFPRegsMode save_fp); |
255 Handle<Map> map, | |
256 Register scratch1, | |
257 Register scratch2, | |
258 SaveFPRegsMode save_fp); | |
259 | 206 |
260 // --------------------------------------------------------------------------- | 207 // --------------------------------------------------------------------------- |
261 // Debugger Support | 208 // Debugger Support |
262 | 209 |
263 void DebugBreak(); | 210 void DebugBreak(); |
264 | 211 |
265 // Generates function and stub prologue code. | 212 // Generates function and stub prologue code. |
266 void StubPrologue(); | 213 void StubPrologue(); |
267 void Prologue(bool code_pre_aging); | 214 void Prologue(bool code_pre_aging); |
268 | 215 |
(...skipping 17 matching lines...) Expand all Loading... |
286 // Find the function context up the context chain. | 233 // Find the function context up the context chain. |
287 void LoadContext(Register dst, int context_chain_length); | 234 void LoadContext(Register dst, int context_chain_length); |
288 | 235 |
289 // Load the global proxy from the current context. | 236 // Load the global proxy from the current context. |
290 void LoadGlobalProxy(Register dst); | 237 void LoadGlobalProxy(Register dst); |
291 | 238 |
292 // Conditionally load the cached Array transitioned map of type | 239 // Conditionally load the cached Array transitioned map of type |
293 // transitioned_kind from the native context if the map in register | 240 // transitioned_kind from the native context if the map in register |
294 // map_in_out is the cached Array map in the native context of | 241 // map_in_out is the cached Array map in the native context of |
295 // expected_kind. | 242 // expected_kind. |
296 void LoadTransitionedArrayMapConditional( | 243 void LoadTransitionedArrayMapConditional(ElementsKind expected_kind, |
297 ElementsKind expected_kind, | 244 ElementsKind transitioned_kind, |
298 ElementsKind transitioned_kind, | 245 Register map_in_out, |
299 Register map_in_out, | 246 Register scratch, |
300 Register scratch, | 247 Label* no_map_match); |
301 Label* no_map_match); | |
302 | 248 |
303 // Load the global function with the given index. | 249 // Load the global function with the given index. |
304 void LoadGlobalFunction(int index, Register function); | 250 void LoadGlobalFunction(int index, Register function); |
305 | 251 |
306 // Load the initial map from the global function. The registers | 252 // Load the initial map from the global function. The registers |
307 // function and map can be the same. | 253 // function and map can be the same. |
308 void LoadGlobalFunctionInitialMap(Register function, Register map); | 254 void LoadGlobalFunctionInitialMap(Register function, Register map); |
309 | 255 |
310 // Push and pop the registers that can hold pointers. | 256 // Push and pop the registers that can hold pointers. |
311 void PushSafepointRegisters() { pushad(); } | 257 void PushSafepointRegisters() { pushad(); } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 void GetWeakValue(Register value, Handle<WeakCell> cell); | 290 void GetWeakValue(Register value, Handle<WeakCell> cell); |
345 | 291 |
346 // Load the value of the weak cell in the value register. Branch to the given | 292 // Load the value of the weak cell in the value register. Branch to the given |
347 // miss label if the weak cell was cleared. | 293 // miss label if the weak cell was cleared. |
348 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); | 294 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); |
349 | 295 |
350 // --------------------------------------------------------------------------- | 296 // --------------------------------------------------------------------------- |
351 // JavaScript invokes | 297 // JavaScript invokes |
352 | 298 |
353 // Invoke the JavaScript function code by either calling or jumping. | 299 // Invoke the JavaScript function code by either calling or jumping. |
354 void InvokeCode(Register code, | |
355 const ParameterCount& expected, | |
356 const ParameterCount& actual, | |
357 InvokeFlag flag, | |
358 const CallWrapper& call_wrapper) { | |
359 InvokeCode(Operand(code), no_reg, expected, actual, flag, call_wrapper); | |
360 } | |
361 | 300 |
362 void InvokeCode(const Operand& code, | 301 void InvokeFunctionCode(Register function, Register new_target, |
363 Register new_target, | 302 const ParameterCount& expected, |
364 const ParameterCount& expected, | 303 const ParameterCount& actual, InvokeFlag flag, |
365 const ParameterCount& actual, | 304 const CallWrapper& call_wrapper); |
366 InvokeFlag flag, | |
367 const CallWrapper& call_wrapper); | |
368 | 305 |
369 // Invoke the JavaScript function in the given register. Changes the | 306 // Invoke the JavaScript function in the given register. Changes the |
370 // current context to the context in the function before invoking. | 307 // current context to the context in the function before invoking. |
371 void InvokeFunction(Register function, | 308 void InvokeFunction(Register function, Register new_target, |
372 Register new_target, | 309 const ParameterCount& actual, InvokeFlag flag, |
373 const ParameterCount& actual, | |
374 InvokeFlag flag, | |
375 const CallWrapper& call_wrapper); | 310 const CallWrapper& call_wrapper); |
376 | 311 |
377 void InvokeFunction(Register function, | 312 void InvokeFunction(Register function, const ParameterCount& expected, |
378 const ParameterCount& expected, | 313 const ParameterCount& actual, InvokeFlag flag, |
379 const ParameterCount& actual, | |
380 InvokeFlag flag, | |
381 const CallWrapper& call_wrapper); | 314 const CallWrapper& call_wrapper); |
382 | 315 |
383 void InvokeFunction(Handle<JSFunction> function, | 316 void InvokeFunction(Handle<JSFunction> function, |
384 const ParameterCount& expected, | 317 const ParameterCount& expected, |
385 const ParameterCount& actual, | 318 const ParameterCount& actual, InvokeFlag flag, |
386 InvokeFlag flag, | |
387 const CallWrapper& call_wrapper); | 319 const CallWrapper& call_wrapper); |
388 | 320 |
389 // Invoke specified builtin JavaScript function. | 321 // Invoke specified builtin JavaScript function. |
390 void InvokeBuiltin(int native_context_index, InvokeFlag flag, | 322 void InvokeBuiltin(int native_context_index, InvokeFlag flag, |
391 const CallWrapper& call_wrapper = NullCallWrapper()); | 323 const CallWrapper& call_wrapper = NullCallWrapper()); |
392 | 324 |
393 // Store the function for the given builtin in the target register. | 325 // Store the function for the given builtin in the target register. |
394 void GetBuiltinFunction(Register target, int native_context_index); | 326 void GetBuiltinFunction(Register target, int native_context_index); |
395 | 327 |
396 // Store the code object for the given builtin in the target register. | |
397 void GetBuiltinEntry(Register target, int native_context_index); | |
398 | |
399 // Expression support | 328 // Expression support |
400 // cvtsi2sd instruction only writes to the low 64-bit of dst register, which | 329 // cvtsi2sd instruction only writes to the low 64-bit of dst register, which |
401 // hinders register renaming and makes dependence chains longer. So we use | 330 // hinders register renaming and makes dependence chains longer. So we use |
402 // xorps to clear the dst register before cvtsi2sd to solve this issue. | 331 // xorps to clear the dst register before cvtsi2sd to solve this issue. |
403 void Cvtsi2sd(XMMRegister dst, Register src) { Cvtsi2sd(dst, Operand(src)); } | 332 void Cvtsi2sd(XMMRegister dst, Register src) { Cvtsi2sd(dst, Operand(src)); } |
404 void Cvtsi2sd(XMMRegister dst, const Operand& src); | 333 void Cvtsi2sd(XMMRegister dst, const Operand& src); |
405 | 334 |
406 // Support for constant splitting. | 335 // Support for constant splitting. |
407 bool IsUnsafeImmediate(const Immediate& x); | 336 bool IsUnsafeImmediate(const Immediate& x); |
408 void SafeMove(Register dst, const Immediate& x); | 337 void SafeMove(Register dst, const Immediate& x); |
409 void SafePush(const Immediate& x); | 338 void SafePush(const Immediate& x); |
410 | 339 |
411 // Compare object type for heap object. | 340 // Compare object type for heap object. |
412 // Incoming register is heap_object and outgoing register is map. | 341 // Incoming register is heap_object and outgoing register is map. |
413 void CmpObjectType(Register heap_object, InstanceType type, Register map); | 342 void CmpObjectType(Register heap_object, InstanceType type, Register map); |
414 | 343 |
415 // Compare instance type for map. | 344 // Compare instance type for map. |
416 void CmpInstanceType(Register map, InstanceType type); | 345 void CmpInstanceType(Register map, InstanceType type); |
417 | 346 |
418 // Check if a map for a JSObject indicates that the object has fast elements. | 347 // Check if a map for a JSObject indicates that the object has fast elements. |
419 // Jump to the specified label if it does not. | 348 // Jump to the specified label if it does not. |
420 void CheckFastElements(Register map, | 349 void CheckFastElements(Register map, Label* fail, |
421 Label* fail, | |
422 Label::Distance distance = Label::kFar); | 350 Label::Distance distance = Label::kFar); |
423 | 351 |
424 // Check if a map for a JSObject indicates that the object can have both smi | 352 // Check if a map for a JSObject indicates that the object can have both smi |
425 // and HeapObject elements. Jump to the specified label if it does not. | 353 // and HeapObject elements. Jump to the specified label if it does not. |
426 void CheckFastObjectElements(Register map, | 354 void CheckFastObjectElements(Register map, Label* fail, |
427 Label* fail, | |
428 Label::Distance distance = Label::kFar); | 355 Label::Distance distance = Label::kFar); |
429 | 356 |
430 // Check if a map for a JSObject indicates that the object has fast smi only | 357 // Check if a map for a JSObject indicates that the object has fast smi only |
431 // elements. Jump to the specified label if it does not. | 358 // elements. Jump to the specified label if it does not. |
432 void CheckFastSmiElements(Register map, | 359 void CheckFastSmiElements(Register map, Label* fail, |
433 Label* fail, | |
434 Label::Distance distance = Label::kFar); | 360 Label::Distance distance = Label::kFar); |
435 | 361 |
436 // Check to see if maybe_number can be stored as a double in | 362 // Check to see if maybe_number can be stored as a double in |
437 // FastDoubleElements. If it can, store it at the index specified by key in | 363 // FastDoubleElements. If it can, store it at the index specified by key in |
438 // the FastDoubleElements array elements, otherwise jump to fail. | 364 // the FastDoubleElements array elements, otherwise jump to fail. |
439 void StoreNumberToDoubleElements(Register maybe_number, | 365 void StoreNumberToDoubleElements(Register maybe_number, Register elements, |
440 Register elements, | 366 Register key, Register scratch1, |
441 Register key, | 367 XMMRegister scratch2, Label* fail, |
442 Register scratch1, | |
443 XMMRegister scratch2, | |
444 Label* fail, | |
445 int offset = 0); | 368 int offset = 0); |
446 | 369 |
447 // Compare an object's map with the specified map. | 370 // Compare an object's map with the specified map. |
448 void CompareMap(Register obj, Handle<Map> map); | 371 void CompareMap(Register obj, Handle<Map> map); |
449 | 372 |
450 // Check if the map of an object is equal to a specified map and branch to | 373 // Check if the map of an object is equal to a specified map and branch to |
451 // label if not. Skip the smi check if not required (object is known to be a | 374 // label if not. Skip the smi check if not required (object is known to be a |
452 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match | 375 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match |
453 // against maps that are ElementsKind transition maps of the specified map. | 376 // against maps that are ElementsKind transition maps of the specified map. |
454 void CheckMap(Register obj, | 377 void CheckMap(Register obj, Handle<Map> map, Label* fail, |
455 Handle<Map> map, | |
456 Label* fail, | |
457 SmiCheckType smi_check_type); | 378 SmiCheckType smi_check_type); |
458 | 379 |
459 // Check if the map of an object is equal to a specified weak map and branch | 380 // Check if the map of an object is equal to a specified weak map and branch |
460 // to a specified target if equal. Skip the smi check if not required | 381 // to a specified target if equal. Skip the smi check if not required |
461 // (object is known to be a heap object) | 382 // (object is known to be a heap object) |
462 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, | 383 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, |
463 Handle<WeakCell> cell, Handle<Code> success, | 384 Handle<WeakCell> cell, Handle<Code> success, |
464 SmiCheckType smi_check_type); | 385 SmiCheckType smi_check_type); |
465 | 386 |
466 // Check if the object in register heap_object is a string. Afterwards the | 387 // Check if the object in register heap_object is a string. Afterwards the |
467 // register map contains the object map and the register instance_type | 388 // register map contains the object map and the register instance_type |
468 // contains the instance_type. The registers map and instance_type can be the | 389 // contains the instance_type. The registers map and instance_type can be the |
469 // same in which case it contains the instance type afterwards. Either of the | 390 // same in which case it contains the instance type afterwards. Either of the |
470 // registers map and instance_type can be the same as heap_object. | 391 // registers map and instance_type can be the same as heap_object. |
471 Condition IsObjectStringType(Register heap_object, | 392 Condition IsObjectStringType(Register heap_object, Register map, |
472 Register map, | |
473 Register instance_type); | 393 Register instance_type); |
474 | 394 |
475 // Check if the object in register heap_object is a name. Afterwards the | 395 // Check if the object in register heap_object is a name. Afterwards the |
476 // register map contains the object map and the register instance_type | 396 // register map contains the object map and the register instance_type |
477 // contains the instance_type. The registers map and instance_type can be the | 397 // contains the instance_type. The registers map and instance_type can be the |
478 // same in which case it contains the instance type afterwards. Either of the | 398 // same in which case it contains the instance type afterwards. Either of the |
479 // registers map and instance_type can be the same as heap_object. | 399 // registers map and instance_type can be the same as heap_object. |
480 Condition IsObjectNameType(Register heap_object, | 400 Condition IsObjectNameType(Register heap_object, Register map, |
481 Register map, | |
482 Register instance_type); | 401 Register instance_type); |
483 | 402 |
484 // FCmp is similar to integer cmp, but requires unsigned | 403 // FCmp is similar to integer cmp, but requires unsigned |
485 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). | 404 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). |
486 void FCmp(); | 405 void FCmp(); |
487 | 406 |
488 void ClampUint8(Register reg); | 407 void ClampUint8(Register reg); |
489 | 408 |
490 void ClampDoubleToUint8(XMMRegister input_reg, | 409 void ClampDoubleToUint8(XMMRegister input_reg, XMMRegister scratch_reg, |
491 XMMRegister scratch_reg, | |
492 Register result_reg); | 410 Register result_reg); |
493 | 411 |
494 void SlowTruncateToI(Register result_reg, Register input_reg, | 412 void SlowTruncateToI(Register result_reg, Register input_reg, |
495 int offset = HeapNumber::kValueOffset - kHeapObjectTag); | 413 int offset = HeapNumber::kValueOffset - kHeapObjectTag); |
496 | 414 |
497 void TruncateHeapNumberToI(Register result_reg, Register input_reg); | 415 void TruncateHeapNumberToI(Register result_reg, Register input_reg); |
498 void TruncateDoubleToI(Register result_reg, XMMRegister input_reg); | 416 void TruncateDoubleToI(Register result_reg, XMMRegister input_reg); |
499 | 417 |
500 void DoubleToI(Register result_reg, XMMRegister input_reg, | 418 void DoubleToI(Register result_reg, XMMRegister input_reg, |
501 XMMRegister scratch, MinusZeroMode minus_zero_mode, | 419 XMMRegister scratch, MinusZeroMode minus_zero_mode, |
(...skipping 17 matching lines...) Expand all Loading... |
519 STATIC_ASSERT(kSmiTag == 0); | 437 STATIC_ASSERT(kSmiTag == 0); |
520 j(not_carry, is_smi); | 438 j(not_carry, is_smi); |
521 } | 439 } |
522 | 440 |
523 void LoadUint32(XMMRegister dst, Register src) { | 441 void LoadUint32(XMMRegister dst, Register src) { |
524 LoadUint32(dst, Operand(src)); | 442 LoadUint32(dst, Operand(src)); |
525 } | 443 } |
526 void LoadUint32(XMMRegister dst, const Operand& src); | 444 void LoadUint32(XMMRegister dst, const Operand& src); |
527 | 445 |
528 // Jump the register contains a smi. | 446 // Jump the register contains a smi. |
529 inline void JumpIfSmi(Register value, | 447 inline void JumpIfSmi(Register value, Label* smi_label, |
530 Label* smi_label, | |
531 Label::Distance distance = Label::kFar) { | 448 Label::Distance distance = Label::kFar) { |
532 test(value, Immediate(kSmiTagMask)); | 449 test(value, Immediate(kSmiTagMask)); |
533 j(zero, smi_label, distance); | 450 j(zero, smi_label, distance); |
534 } | 451 } |
535 // Jump if the operand is a smi. | 452 // Jump if the operand is a smi. |
536 inline void JumpIfSmi(Operand value, | 453 inline void JumpIfSmi(Operand value, Label* smi_label, |
537 Label* smi_label, | |
538 Label::Distance distance = Label::kFar) { | 454 Label::Distance distance = Label::kFar) { |
539 test(value, Immediate(kSmiTagMask)); | 455 test(value, Immediate(kSmiTagMask)); |
540 j(zero, smi_label, distance); | 456 j(zero, smi_label, distance); |
541 } | 457 } |
542 // Jump if register contain a non-smi. | 458 // Jump if register contain a non-smi. |
543 inline void JumpIfNotSmi(Register value, | 459 inline void JumpIfNotSmi(Register value, Label* not_smi_label, |
544 Label* not_smi_label, | |
545 Label::Distance distance = Label::kFar) { | 460 Label::Distance distance = Label::kFar) { |
546 test(value, Immediate(kSmiTagMask)); | 461 test(value, Immediate(kSmiTagMask)); |
547 j(not_zero, not_smi_label, distance); | 462 j(not_zero, not_smi_label, distance); |
548 } | 463 } |
549 | 464 |
550 void LoadInstanceDescriptors(Register map, Register descriptors); | 465 void LoadInstanceDescriptors(Register map, Register descriptors); |
551 void EnumLength(Register dst, Register map); | 466 void EnumLength(Register dst, Register map); |
552 void NumberOfOwnDescriptors(Register dst, Register map); | 467 void NumberOfOwnDescriptors(Register dst, Register map); |
553 void LoadAccessor(Register dst, Register holder, int accessor_index, | 468 void LoadAccessor(Register dst, Register holder, int accessor_index, |
554 AccessorComponent accessor); | 469 AccessorComponent accessor); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 | 524 |
610 // Unlink the stack handler on top of the stack from the stack handler chain. | 525 // Unlink the stack handler on top of the stack from the stack handler chain. |
611 void PopStackHandler(); | 526 void PopStackHandler(); |
612 | 527 |
613 // --------------------------------------------------------------------------- | 528 // --------------------------------------------------------------------------- |
614 // Inline caching support | 529 // Inline caching support |
615 | 530 |
616 // Generate code for checking access rights - used for security checks | 531 // Generate code for checking access rights - used for security checks |
617 // on access to global objects across environments. The holder register | 532 // on access to global objects across environments. The holder register |
618 // is left untouched, but the scratch register is clobbered. | 533 // is left untouched, but the scratch register is clobbered. |
619 void CheckAccessGlobalProxy(Register holder_reg, | 534 void CheckAccessGlobalProxy(Register holder_reg, Register scratch1, |
620 Register scratch1, | 535 Register scratch2, Label* miss); |
621 Register scratch2, | |
622 Label* miss); | |
623 | 536 |
624 void GetNumberHash(Register r0, Register scratch); | 537 void GetNumberHash(Register r0, Register scratch); |
625 | 538 |
626 void LoadFromNumberDictionary(Label* miss, | 539 void LoadFromNumberDictionary(Label* miss, Register elements, Register key, |
627 Register elements, | 540 Register r0, Register r1, Register r2, |
628 Register key, | |
629 Register r0, | |
630 Register r1, | |
631 Register r2, | |
632 Register result); | 541 Register result); |
633 | 542 |
634 | |
635 // --------------------------------------------------------------------------- | 543 // --------------------------------------------------------------------------- |
636 // Allocation support | 544 // Allocation support |
637 | 545 |
638 // Allocate an object in new space or old space. If the given space | 546 // Allocate an object in new space or old space. If the given space |
639 // is exhausted control continues at the gc_required label. The allocated | 547 // is exhausted control continues at the gc_required label. The allocated |
640 // object is returned in result and end of the new object is returned in | 548 // object is returned in result and end of the new object is returned in |
641 // result_end. The register scratch can be passed as no_reg in which case | 549 // result_end. The register scratch can be passed as no_reg in which case |
642 // an additional object reference will be added to the reloc info. The | 550 // an additional object reference will be added to the reloc info. The |
643 // returned pointers in result and result_end have not yet been tagged as | 551 // returned pointers in result and result_end have not yet been tagged as |
644 // heap objects. If result_contains_top_on_entry is true the content of | 552 // heap objects. If result_contains_top_on_entry is true the content of |
645 // result is known to be the allocation top on entry (could be result_end | 553 // result is known to be the allocation top on entry (could be result_end |
646 // from a previous call). If result_contains_top_on_entry is true scratch | 554 // from a previous call). If result_contains_top_on_entry is true scratch |
647 // should be no_reg as it is never used. | 555 // should be no_reg as it is never used. |
648 void Allocate(int object_size, | 556 void Allocate(int object_size, Register result, Register result_end, |
649 Register result, | 557 Register scratch, Label* gc_required, AllocationFlags flags); |
650 Register result_end, | |
651 Register scratch, | |
652 Label* gc_required, | |
653 AllocationFlags flags); | |
654 | 558 |
655 void Allocate(int header_size, | 559 void Allocate(int header_size, ScaleFactor element_size, |
656 ScaleFactor element_size, | 560 Register element_count, RegisterValueType element_count_type, |
657 Register element_count, | 561 Register result, Register result_end, Register scratch, |
658 RegisterValueType element_count_type, | 562 Label* gc_required, AllocationFlags flags); |
659 Register result, | |
660 Register result_end, | |
661 Register scratch, | |
662 Label* gc_required, | |
663 AllocationFlags flags); | |
664 | 563 |
665 void Allocate(Register object_size, | 564 void Allocate(Register object_size, Register result, Register result_end, |
666 Register result, | 565 Register scratch, Label* gc_required, AllocationFlags flags); |
667 Register result_end, | |
668 Register scratch, | |
669 Label* gc_required, | |
670 AllocationFlags flags); | |
671 | 566 |
672 // Allocate a heap number in new space with undefined value. The | 567 // Allocate a heap number in new space with undefined value. The |
673 // register scratch2 can be passed as no_reg; the others must be | 568 // register scratch2 can be passed as no_reg; the others must be |
674 // valid registers. Returns tagged pointer in result register, or | 569 // valid registers. Returns tagged pointer in result register, or |
675 // jumps to gc_required if new space is full. | 570 // jumps to gc_required if new space is full. |
676 void AllocateHeapNumber(Register result, | 571 void AllocateHeapNumber(Register result, Register scratch1, Register scratch2, |
677 Register scratch1, | 572 Label* gc_required, MutableMode mode = IMMUTABLE); |
678 Register scratch2, | |
679 Label* gc_required, | |
680 MutableMode mode = IMMUTABLE); | |
681 | 573 |
682 // Allocate a sequential string. All the header fields of the string object | 574 // Allocate a sequential string. All the header fields of the string object |
683 // are initialized. | 575 // are initialized. |
684 void AllocateTwoByteString(Register result, | 576 void AllocateTwoByteString(Register result, Register length, |
685 Register length, | 577 Register scratch1, Register scratch2, |
686 Register scratch1, | 578 Register scratch3, Label* gc_required); |
687 Register scratch2, | |
688 Register scratch3, | |
689 Label* gc_required); | |
690 void AllocateOneByteString(Register result, Register length, | 579 void AllocateOneByteString(Register result, Register length, |
691 Register scratch1, Register scratch2, | 580 Register scratch1, Register scratch2, |
692 Register scratch3, Label* gc_required); | 581 Register scratch3, Label* gc_required); |
693 void AllocateOneByteString(Register result, int length, Register scratch1, | 582 void AllocateOneByteString(Register result, int length, Register scratch1, |
694 Register scratch2, Label* gc_required); | 583 Register scratch2, Label* gc_required); |
695 | 584 |
696 // Allocate a raw cons string object. Only the map field of the result is | 585 // Allocate a raw cons string object. Only the map field of the result is |
697 // initialized. | 586 // initialized. |
698 void AllocateTwoByteConsString(Register result, | 587 void AllocateTwoByteConsString(Register result, Register scratch1, |
699 Register scratch1, | 588 Register scratch2, Label* gc_required); |
700 Register scratch2, | |
701 Label* gc_required); | |
702 void AllocateOneByteConsString(Register result, Register scratch1, | 589 void AllocateOneByteConsString(Register result, Register scratch1, |
703 Register scratch2, Label* gc_required); | 590 Register scratch2, Label* gc_required); |
704 | 591 |
705 // Allocate a raw sliced string object. Only the map field of the result is | 592 // Allocate a raw sliced string object. Only the map field of the result is |
706 // initialized. | 593 // initialized. |
707 void AllocateTwoByteSlicedString(Register result, | 594 void AllocateTwoByteSlicedString(Register result, Register scratch1, |
708 Register scratch1, | 595 Register scratch2, Label* gc_required); |
709 Register scratch2, | |
710 Label* gc_required); | |
711 void AllocateOneByteSlicedString(Register result, Register scratch1, | 596 void AllocateOneByteSlicedString(Register result, Register scratch1, |
712 Register scratch2, Label* gc_required); | 597 Register scratch2, Label* gc_required); |
713 | 598 |
714 // Copy memory, byte-by-byte, from source to destination. Not optimized for | 599 // Copy memory, byte-by-byte, from source to destination. Not optimized for |
715 // long or aligned copies. | 600 // long or aligned copies. |
716 // The contents of index and scratch are destroyed. | 601 // The contents of index and scratch are destroyed. |
717 void CopyBytes(Register source, | 602 void CopyBytes(Register source, Register destination, Register length, |
718 Register destination, | |
719 Register length, | |
720 Register scratch); | 603 Register scratch); |
721 | 604 |
722 // Initialize fields with filler values. Fields starting at |current_address| | 605 // Initialize fields with filler values. Fields starting at |current_address| |
723 // not including |end_address| are overwritten with the value in |filler|. At | 606 // not including |end_address| are overwritten with the value in |filler|. At |
724 // the end the loop, |current_address| takes the value of |end_address|. | 607 // the end the loop, |current_address| takes the value of |end_address|. |
725 void InitializeFieldsWithFiller(Register current_address, | 608 void InitializeFieldsWithFiller(Register current_address, |
726 Register end_address, Register filler); | 609 Register end_address, Register filler); |
727 | 610 |
728 // --------------------------------------------------------------------------- | 611 // --------------------------------------------------------------------------- |
729 // Support functions. | 612 // Support functions. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 // Call a code stub. Generate the code if necessary. | 646 // Call a code stub. Generate the code if necessary. |
764 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); | 647 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); |
765 | 648 |
766 // Tail call a code stub (jump). Generate the code if necessary. | 649 // Tail call a code stub (jump). Generate the code if necessary. |
767 void TailCallStub(CodeStub* stub); | 650 void TailCallStub(CodeStub* stub); |
768 | 651 |
769 // Return from a code stub after popping its arguments. | 652 // Return from a code stub after popping its arguments. |
770 void StubReturn(int argc); | 653 void StubReturn(int argc); |
771 | 654 |
772 // Call a runtime routine. | 655 // Call a runtime routine. |
773 void CallRuntime(const Runtime::Function* f, | 656 void CallRuntime(const Runtime::Function* f, int num_arguments, |
774 int num_arguments, | |
775 SaveFPRegsMode save_doubles = kDontSaveFPRegs); | 657 SaveFPRegsMode save_doubles = kDontSaveFPRegs); |
776 void CallRuntimeSaveDoubles(Runtime::FunctionId id) { | 658 void CallRuntimeSaveDoubles(Runtime::FunctionId id) { |
777 const Runtime::Function* function = Runtime::FunctionForId(id); | 659 const Runtime::Function* function = Runtime::FunctionForId(id); |
778 CallRuntime(function, function->nargs, kSaveFPRegs); | 660 CallRuntime(function, function->nargs, kSaveFPRegs); |
779 } | 661 } |
780 | 662 |
781 // Convenience function: Same as above, but takes the fid instead. | 663 // Convenience function: Same as above, but takes the fid instead. |
782 void CallRuntime(Runtime::FunctionId id, | 664 void CallRuntime(Runtime::FunctionId id, int num_arguments, |
783 int num_arguments, | |
784 SaveFPRegsMode save_doubles = kDontSaveFPRegs) { | 665 SaveFPRegsMode save_doubles = kDontSaveFPRegs) { |
785 CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles); | 666 CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles); |
786 } | 667 } |
787 | 668 |
788 // Convenience function: call an external reference. | 669 // Convenience function: call an external reference. |
789 void CallExternalReference(ExternalReference ref, int num_arguments); | 670 void CallExternalReference(ExternalReference ref, int num_arguments); |
790 | 671 |
791 // Tail call of a runtime routine (jump). | 672 // Tail call of a runtime routine (jump). |
792 // Like JumpToExternalReference, but also takes care of passing the number | 673 // Like JumpToExternalReference, but also takes care of passing the number |
793 // of parameters. | 674 // of parameters. |
794 void TailCallExternalReference(const ExternalReference& ext, | 675 void TailCallExternalReference(const ExternalReference& ext, |
795 int num_arguments, | 676 int num_arguments, int result_size); |
796 int result_size); | |
797 | 677 |
798 // Convenience function: tail call a runtime routine (jump). | 678 // Convenience function: tail call a runtime routine (jump). |
799 void TailCallRuntime(Runtime::FunctionId fid, | 679 void TailCallRuntime(Runtime::FunctionId fid, int num_arguments, |
800 int num_arguments, | |
801 int result_size); | 680 int result_size); |
802 | 681 |
803 // Before calling a C-function from generated code, align arguments on stack. | 682 // Before calling a C-function from generated code, align arguments on stack. |
804 // After aligning the frame, arguments must be stored in esp[0], esp[4], | 683 // After aligning the frame, arguments must be stored in esp[0], esp[4], |
805 // etc., not pushed. The argument count assumes all arguments are word sized. | 684 // etc., not pushed. The argument count assumes all arguments are word sized. |
806 // Some compilers/platforms require the stack to be aligned when calling | 685 // Some compilers/platforms require the stack to be aligned when calling |
807 // C++ code. | 686 // C++ code. |
808 // Needs a scratch register to do some arithmetic. This register will be | 687 // Needs a scratch register to do some arithmetic. This register will be |
809 // trashed. | 688 // trashed. |
810 void PrepareCallCFunction(int num_arguments, Register scratch); | 689 void PrepareCallCFunction(int num_arguments, Register scratch); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 | 772 |
894 // --------------------------------------------------------------------------- | 773 // --------------------------------------------------------------------------- |
895 // StatsCounter support | 774 // StatsCounter support |
896 | 775 |
897 void SetCounter(StatsCounter* counter, int value); | 776 void SetCounter(StatsCounter* counter, int value); |
898 void IncrementCounter(StatsCounter* counter, int value); | 777 void IncrementCounter(StatsCounter* counter, int value); |
899 void DecrementCounter(StatsCounter* counter, int value); | 778 void DecrementCounter(StatsCounter* counter, int value); |
900 void IncrementCounter(Condition cc, StatsCounter* counter, int value); | 779 void IncrementCounter(Condition cc, StatsCounter* counter, int value); |
901 void DecrementCounter(Condition cc, StatsCounter* counter, int value); | 780 void DecrementCounter(Condition cc, StatsCounter* counter, int value); |
902 | 781 |
903 | |
904 // --------------------------------------------------------------------------- | 782 // --------------------------------------------------------------------------- |
905 // Debugging | 783 // Debugging |
906 | 784 |
907 // Calls Abort(msg) if the condition cc is not satisfied. | 785 // Calls Abort(msg) if the condition cc is not satisfied. |
908 // Use --debug_code to enable. | 786 // Use --debug_code to enable. |
909 void Assert(Condition cc, BailoutReason reason); | 787 void Assert(Condition cc, BailoutReason reason); |
910 | 788 |
911 void AssertFastElements(Register elements); | 789 void AssertFastElements(Register elements); |
912 | 790 |
913 // Like Assert(), but always enabled. | 791 // Like Assert(), but always enabled. |
(...skipping 30 matching lines...) Expand all Loading... |
944 | 822 |
945 // Checks if the given register or operand is a unique name | 823 // Checks if the given register or operand is a unique name |
946 void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name, | 824 void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name, |
947 Label::Distance distance = Label::kFar) { | 825 Label::Distance distance = Label::kFar) { |
948 JumpIfNotUniqueNameInstanceType(Operand(reg), not_unique_name, distance); | 826 JumpIfNotUniqueNameInstanceType(Operand(reg), not_unique_name, distance); |
949 } | 827 } |
950 | 828 |
951 void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name, | 829 void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name, |
952 Label::Distance distance = Label::kFar); | 830 Label::Distance distance = Label::kFar); |
953 | 831 |
954 void EmitSeqStringSetCharCheck(Register string, | 832 void EmitSeqStringSetCharCheck(Register string, Register index, |
955 Register index, | 833 Register value, uint32_t encoding_mask); |
956 Register value, | |
957 uint32_t encoding_mask); | |
958 | 834 |
959 static int SafepointRegisterStackIndex(Register reg) { | 835 static int SafepointRegisterStackIndex(Register reg) { |
960 return SafepointRegisterStackIndex(reg.code()); | 836 return SafepointRegisterStackIndex(reg.code()); |
961 } | 837 } |
962 | 838 |
963 // Load the type feedback vector from a JavaScript frame. | 839 // Load the type feedback vector from a JavaScript frame. |
964 void EmitLoadTypeFeedbackVector(Register vector); | 840 void EmitLoadTypeFeedbackVector(Register vector); |
965 | 841 |
966 // Activation support. | 842 // Activation support. |
967 void EnterFrame(StackFrame::Type type); | 843 void EnterFrame(StackFrame::Type type); |
(...skipping 29 matching lines...) Expand all Loading... |
997 Register scratch1, Label* found); | 873 Register scratch1, Label* found); |
998 | 874 |
999 private: | 875 private: |
1000 bool generating_stub_; | 876 bool generating_stub_; |
1001 bool has_frame_; | 877 bool has_frame_; |
1002 // This handle will be patched with the code object on installation. | 878 // This handle will be patched with the code object on installation. |
1003 Handle<Object> code_object_; | 879 Handle<Object> code_object_; |
1004 | 880 |
1005 // Helper functions for generating invokes. | 881 // Helper functions for generating invokes. |
1006 void InvokePrologue(const ParameterCount& expected, | 882 void InvokePrologue(const ParameterCount& expected, |
1007 const ParameterCount& actual, | 883 const ParameterCount& actual, Label* done, |
1008 Label* done, | 884 bool* definitely_mismatches, InvokeFlag flag, |
1009 bool* definitely_mismatches, | |
1010 InvokeFlag flag, | |
1011 Label::Distance done_distance, | 885 Label::Distance done_distance, |
1012 const CallWrapper& call_wrapper); | 886 const CallWrapper& call_wrapper); |
1013 | 887 |
| 888 void FloodFunctionIfStepping(Register fun, Register new_target, |
| 889 const ParameterCount& expected, |
| 890 const ParameterCount& actual); |
| 891 |
1014 void EnterExitFramePrologue(); | 892 void EnterExitFramePrologue(); |
1015 void EnterExitFrameEpilogue(int argc, bool save_doubles); | 893 void EnterExitFrameEpilogue(int argc, bool save_doubles); |
1016 | 894 |
1017 void LeaveExitFrameEpilogue(bool restore_context); | 895 void LeaveExitFrameEpilogue(bool restore_context); |
1018 | 896 |
1019 // Allocation support helpers. | 897 // Allocation support helpers. |
1020 void LoadAllocationTopHelper(Register result, | 898 void LoadAllocationTopHelper(Register result, Register scratch, |
1021 Register scratch, | |
1022 AllocationFlags flags); | 899 AllocationFlags flags); |
1023 | 900 |
1024 void UpdateAllocationTopHelper(Register result_end, | 901 void UpdateAllocationTopHelper(Register result_end, Register scratch, |
1025 Register scratch, | |
1026 AllocationFlags flags); | 902 AllocationFlags flags); |
1027 | 903 |
1028 // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. | 904 // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. |
1029 void InNewSpace(Register object, | 905 void InNewSpace(Register object, Register scratch, Condition cc, |
1030 Register scratch, | |
1031 Condition cc, | |
1032 Label* condition_met, | 906 Label* condition_met, |
1033 Label::Distance condition_met_distance = Label::kFar); | 907 Label::Distance condition_met_distance = Label::kFar); |
1034 | 908 |
1035 // Helper for finding the mark bits for an address. Afterwards, the | 909 // Helper for finding the mark bits for an address. Afterwards, the |
1036 // 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 |
1037 // 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 |
1038 // unchanged. | 912 // unchanged. |
1039 inline void GetMarkBits(Register addr_reg, | 913 inline void GetMarkBits(Register addr_reg, Register bitmap_reg, |
1040 Register bitmap_reg, | |
1041 Register mask_reg); | 914 Register mask_reg); |
1042 | 915 |
1043 // Compute memory operands for safepoint stack slots. | 916 // Compute memory operands for safepoint stack slots. |
1044 Operand SafepointRegisterSlot(Register reg); | 917 Operand SafepointRegisterSlot(Register reg); |
1045 static int SafepointRegisterStackIndex(int reg_code); | 918 static int SafepointRegisterStackIndex(int reg_code); |
1046 | 919 |
1047 // Needs access to SafepointRegisterStackIndex for compiled frame | 920 // Needs access to SafepointRegisterStackIndex for compiled frame |
1048 // traversal. | 921 // traversal. |
1049 friend class StandardFrame; | 922 friend class StandardFrame; |
1050 }; | 923 }; |
1051 | 924 |
1052 | |
1053 // The code patcher is used to patch (typically) small parts of code e.g. for | 925 // The code patcher is used to patch (typically) small parts of code e.g. for |
1054 // debugging and other types of instrumentation. When using the code patcher | 926 // debugging and other types of instrumentation. When using the code patcher |
1055 // the exact number of bytes specified must be emitted. Is not legal to emit | 927 // the exact number of bytes specified must be emitted. Is not legal to emit |
1056 // relocation information. If any of these constraints are violated it causes | 928 // relocation information. If any of these constraints are violated it causes |
1057 // an assertion. | 929 // an assertion. |
1058 class CodePatcher { | 930 class CodePatcher { |
1059 public: | 931 public: |
1060 CodePatcher(byte* address, int size); | 932 CodePatcher(byte* address, int size); |
1061 ~CodePatcher(); | 933 ~CodePatcher(); |
1062 | 934 |
1063 // Macro assembler to emit code. | 935 // Macro assembler to emit code. |
1064 MacroAssembler* masm() { return &masm_; } | 936 MacroAssembler* masm() { return &masm_; } |
1065 | 937 |
1066 private: | 938 private: |
1067 byte* address_; // The address of the code being patched. | 939 byte* address_; // The address of the code being patched. |
1068 int size_; // Number of bytes of the expected patch size. | 940 int size_; // Number of bytes of the expected patch size. |
1069 MacroAssembler masm_; // Macro assembler used to generate the code. | 941 MacroAssembler masm_; // Macro assembler used to generate the code. |
1070 }; | 942 }; |
1071 | 943 |
1072 | |
1073 // ----------------------------------------------------------------------------- | 944 // ----------------------------------------------------------------------------- |
1074 // Static helper functions. | 945 // Static helper functions. |
1075 | 946 |
1076 // Generate an Operand for loading a field from an object. | 947 // Generate an Operand for loading a field from an object. |
1077 inline Operand FieldOperand(Register object, int offset) { | 948 inline Operand FieldOperand(Register object, int offset) { |
1078 return Operand(object, offset - kHeapObjectTag); | 949 return Operand(object, offset - kHeapObjectTag); |
1079 } | 950 } |
1080 | 951 |
1081 | |
1082 // Generate an Operand for loading an indexed field from an object. | 952 // Generate an Operand for loading an indexed field from an object. |
1083 inline Operand FieldOperand(Register object, | 953 inline Operand FieldOperand(Register object, Register index, ScaleFactor scale, |
1084 Register index, | |
1085 ScaleFactor scale, | |
1086 int offset) { | 954 int offset) { |
1087 return Operand(object, index, scale, offset - kHeapObjectTag); | 955 return Operand(object, index, scale, offset - kHeapObjectTag); |
1088 } | 956 } |
1089 | 957 |
1090 | 958 inline Operand FixedArrayElementOperand(Register array, Register index_as_smi, |
1091 inline Operand FixedArrayElementOperand(Register array, | |
1092 Register index_as_smi, | |
1093 int additional_offset = 0) { | 959 int additional_offset = 0) { |
1094 int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize; | 960 int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize; |
1095 return FieldOperand(array, index_as_smi, times_half_pointer_size, offset); | 961 return FieldOperand(array, index_as_smi, times_half_pointer_size, offset); |
1096 } | 962 } |
1097 | 963 |
1098 | |
1099 inline Operand ContextOperand(Register context, int index) { | 964 inline Operand ContextOperand(Register context, int index) { |
1100 return Operand(context, Context::SlotOffset(index)); | 965 return Operand(context, Context::SlotOffset(index)); |
1101 } | 966 } |
1102 | 967 |
1103 | |
1104 inline Operand ContextOperand(Register context, Register index) { | 968 inline Operand ContextOperand(Register context, Register index) { |
1105 return Operand(context, index, times_pointer_size, Context::SlotOffset(0)); | 969 return Operand(context, index, times_pointer_size, Context::SlotOffset(0)); |
1106 } | 970 } |
1107 | 971 |
1108 | |
1109 inline Operand GlobalObjectOperand() { | 972 inline Operand GlobalObjectOperand() { |
1110 return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX); | 973 return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX); |
1111 } | 974 } |
1112 | 975 |
1113 | |
1114 #ifdef GENERATED_CODE_COVERAGE | 976 #ifdef GENERATED_CODE_COVERAGE |
1115 extern void LogGeneratedCodeCoverage(const char* file_line); | 977 extern void LogGeneratedCodeCoverage(const char* file_line); |
1116 #define CODE_COVERAGE_STRINGIFY(x) #x | 978 #define CODE_COVERAGE_STRINGIFY(x) #x |
1117 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) | 979 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) |
1118 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) | 980 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) |
1119 #define ACCESS_MASM(masm) { \ | 981 #define ACCESS_MASM(masm) { \ |
1120 byte* ia32_coverage_function = \ | 982 byte* ia32_coverage_function = \ |
1121 reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \ | 983 reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \ |
1122 masm->pushfd(); \ | 984 masm->pushfd(); \ |
1123 masm->pushad(); \ | 985 masm->pushad(); \ |
1124 masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ | 986 masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ |
1125 masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \ | 987 masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \ |
1126 masm->pop(eax); \ | 988 masm->pop(eax); \ |
1127 masm->popad(); \ | 989 masm->popad(); \ |
1128 masm->popfd(); \ | 990 masm->popfd(); \ |
1129 } \ | 991 } \ |
1130 masm-> | 992 masm-> |
1131 #else | 993 #else |
1132 #define ACCESS_MASM(masm) masm-> | 994 #define ACCESS_MASM(masm) masm-> |
1133 #endif | 995 #endif |
1134 | 996 |
1135 | |
1136 } // namespace internal | 997 } // namespace internal |
1137 } // namespace v8 | 998 } // namespace v8 |
1138 | 999 |
1139 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 1000 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
OLD | NEW |