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