| 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_X87_MACRO_ASSEMBLER_X87_H_ | 5 #ifndef V8_X87_MACRO_ASSEMBLER_X87_H_ |
| 6 #define V8_X87_MACRO_ASSEMBLER_X87_H_ | 6 #define V8_X87_MACRO_ASSEMBLER_X87_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, Register scratch, | 105 Register addr, Register scratch, |
| 119 SaveFPRegsMode save_fp, | 106 SaveFPRegsMode save_fp, |
| 120 RememberedSetFinalAction and_then); | 107 RememberedSetFinalAction and_then); |
| 121 | 108 |
| 122 void CheckPageFlag(Register object, | 109 void CheckPageFlag(Register object, Register scratch, int mask, Condition cc, |
| 123 Register scratch, | |
| 124 int mask, | |
| 125 Condition cc, | |
| 126 Label* condition_met, | 110 Label* condition_met, |
| 127 Label::Distance condition_met_distance = Label::kFar); | 111 Label::Distance condition_met_distance = Label::kFar); |
| 128 | 112 |
| 129 void CheckPageFlagForMap( | 113 void CheckPageFlagForMap( |
| 130 Handle<Map> map, | 114 Handle<Map> map, int mask, Condition cc, Label* condition_met, |
| 131 int mask, | |
| 132 Condition cc, | |
| 133 Label* condition_met, | |
| 134 Label::Distance condition_met_distance = Label::kFar); | 115 Label::Distance condition_met_distance = Label::kFar); |
| 135 | 116 |
| 136 // 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. |
| 137 // 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. |
| 138 void JumpIfNotInNewSpace(Register object, | 119 void JumpIfNotInNewSpace(Register object, Register scratch, Label* branch, |
| 139 Register scratch, | |
| 140 Label* branch, | |
| 141 Label::Distance distance = Label::kFar) { | 120 Label::Distance distance = Label::kFar) { |
| 142 InNewSpace(object, scratch, zero, branch, distance); | 121 InNewSpace(object, scratch, zero, branch, distance); |
| 143 } | 122 } |
| 144 | 123 |
| 145 // 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. |
| 146 // 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. |
| 147 void JumpIfInNewSpace(Register object, | 126 void JumpIfInNewSpace(Register object, Register scratch, Label* branch, |
| 148 Register scratch, | |
| 149 Label* branch, | |
| 150 Label::Distance distance = Label::kFar) { | 127 Label::Distance distance = Label::kFar) { |
| 151 InNewSpace(object, scratch, not_zero, branch, distance); | 128 InNewSpace(object, scratch, not_zero, branch, distance); |
| 152 } | 129 } |
| 153 | 130 |
| 154 // 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! |
| 155 void HasColor(Register object, | 132 void HasColor(Register object, Register scratch0, Register scratch1, |
| 156 Register scratch0, | 133 Label* has_color, Label::Distance has_color_distance, |
| 157 Register scratch1, | 134 int first_bit, int second_bit); |
| 158 Label* has_color, | |
| 159 Label::Distance has_color_distance, | |
| 160 int first_bit, | |
| 161 int second_bit); | |
| 162 | 135 |
| 163 void JumpIfBlack(Register object, | 136 void JumpIfBlack(Register object, Register scratch0, Register scratch1, |
| 164 Register scratch0, | |
| 165 Register scratch1, | |
| 166 Label* on_black, | 137 Label* on_black, |
| 167 Label::Distance on_black_distance = Label::kFar); | 138 Label::Distance on_black_distance = Label::kFar); |
| 168 | 139 |
| 169 // 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 |
| 170 // 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 |
| 171 // 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 |
| 172 // 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 |
| 173 // incremental marker can fix its assumptions. | 144 // incremental marker can fix its assumptions. |
| 174 void EnsureNotWhite(Register object, | 145 void EnsureNotWhite(Register object, Register scratch1, Register scratch2, |
| 175 Register scratch1, | |
| 176 Register scratch2, | |
| 177 Label* object_is_white_and_not_data, | 146 Label* object_is_white_and_not_data, |
| 178 Label::Distance distance); | 147 Label::Distance distance); |
| 179 | 148 |
| 180 // 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. |
| 181 // |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 |
| 182 // stored. value and scratch registers are clobbered by the operation. | 151 // stored. value and scratch registers are clobbered by the operation. |
| 183 // 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 |
| 184 // the tagged HeapObject pointer. For use with FieldOperand(reg, off). | 153 // the tagged HeapObject pointer. For use with FieldOperand(reg, off). |
| 185 void RecordWriteField( | 154 void RecordWriteField( |
| 186 Register object, int offset, Register value, Register scratch, | 155 Register object, int offset, Register value, Register scratch, |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 // Find the function context up the context chain. | 233 // Find the function context up the context chain. |
| 265 void LoadContext(Register dst, int context_chain_length); | 234 void LoadContext(Register dst, int context_chain_length); |
| 266 | 235 |
| 267 // Load the global proxy from the current context. | 236 // Load the global proxy from the current context. |
| 268 void LoadGlobalProxy(Register dst); | 237 void LoadGlobalProxy(Register dst); |
| 269 | 238 |
| 270 // Conditionally load the cached Array transitioned map of type | 239 // Conditionally load the cached Array transitioned map of type |
| 271 // transitioned_kind from the native context if the map in register | 240 // transitioned_kind from the native context if the map in register |
| 272 // 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 |
| 273 // expected_kind. | 242 // expected_kind. |
| 274 void LoadTransitionedArrayMapConditional( | 243 void LoadTransitionedArrayMapConditional(ElementsKind expected_kind, |
| 275 ElementsKind expected_kind, | 244 ElementsKind transitioned_kind, |
| 276 ElementsKind transitioned_kind, | 245 Register map_in_out, |
| 277 Register map_in_out, | 246 Register scratch, |
| 278 Register scratch, | 247 Label* no_map_match); |
| 279 Label* no_map_match); | |
| 280 | 248 |
| 281 // Load the global function with the given index. | 249 // Load the global function with the given index. |
| 282 void LoadGlobalFunction(int index, Register function); | 250 void LoadGlobalFunction(int index, Register function); |
| 283 | 251 |
| 284 // Load the initial map from the global function. The registers | 252 // Load the initial map from the global function. The registers |
| 285 // function and map can be the same. | 253 // function and map can be the same. |
| 286 void LoadGlobalFunctionInitialMap(Register function, Register map); | 254 void LoadGlobalFunctionInitialMap(Register function, Register map); |
| 287 | 255 |
| 288 // Push and pop the registers that can hold pointers. | 256 // Push and pop the registers that can hold pointers. |
| 289 void PushSafepointRegisters() { pushad(); } | 257 void PushSafepointRegisters() { pushad(); } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 317 } | 285 } |
| 318 | 286 |
| 319 void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch); | 287 void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch); |
| 320 void GetWeakValue(Register value, Handle<WeakCell> cell); | 288 void GetWeakValue(Register value, Handle<WeakCell> cell); |
| 321 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); | 289 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); |
| 322 | 290 |
| 323 // --------------------------------------------------------------------------- | 291 // --------------------------------------------------------------------------- |
| 324 // JavaScript invokes | 292 // JavaScript invokes |
| 325 | 293 |
| 326 // Invoke the JavaScript function code by either calling or jumping. | 294 // Invoke the JavaScript function code by either calling or jumping. |
| 327 void InvokeCode(Register code, | |
| 328 const ParameterCount& expected, | |
| 329 const ParameterCount& actual, | |
| 330 InvokeFlag flag, | |
| 331 const CallWrapper& call_wrapper) { | |
| 332 InvokeCode(Operand(code), no_reg, expected, actual, flag, call_wrapper); | |
| 333 } | |
| 334 | 295 |
| 335 void InvokeCode(const Operand& code, Register new_target, | 296 void InvokeFunctionCode(Register function, Register new_target, |
| 336 const ParameterCount& expected, const ParameterCount& actual, | 297 const ParameterCount& expected, |
| 337 InvokeFlag flag, const CallWrapper& call_wrapper); | 298 const ParameterCount& actual, InvokeFlag flag, |
| 299 const CallWrapper& call_wrapper); |
| 338 | 300 |
| 339 // Invoke the JavaScript function in the given register. Changes the | 301 // Invoke the JavaScript function in the given register. Changes the |
| 340 // current context to the context in the function before invoking. | 302 // current context to the context in the function before invoking. |
| 341 void InvokeFunction(Register function, Register new_target, | 303 void InvokeFunction(Register function, Register new_target, |
| 342 const ParameterCount& actual, InvokeFlag flag, | 304 const ParameterCount& actual, InvokeFlag flag, |
| 343 const CallWrapper& call_wrapper); | 305 const CallWrapper& call_wrapper); |
| 344 | 306 |
| 345 void InvokeFunction(Register function, | 307 void InvokeFunction(Register function, const ParameterCount& expected, |
| 346 const ParameterCount& expected, | 308 const ParameterCount& actual, InvokeFlag flag, |
| 347 const ParameterCount& actual, | |
| 348 InvokeFlag flag, | |
| 349 const CallWrapper& call_wrapper); | 309 const CallWrapper& call_wrapper); |
| 350 | 310 |
| 351 void InvokeFunction(Handle<JSFunction> function, | 311 void InvokeFunction(Handle<JSFunction> function, |
| 352 const ParameterCount& expected, | 312 const ParameterCount& expected, |
| 353 const ParameterCount& actual, | 313 const ParameterCount& actual, InvokeFlag flag, |
| 354 InvokeFlag flag, | |
| 355 const CallWrapper& call_wrapper); | 314 const CallWrapper& call_wrapper); |
| 356 | 315 |
| 357 // Invoke specified builtin JavaScript function. | 316 // Invoke specified builtin JavaScript function. |
| 358 void InvokeBuiltin(int native_context_index, InvokeFlag flag, | 317 void InvokeBuiltin(int native_context_index, InvokeFlag flag, |
| 359 const CallWrapper& call_wrapper = NullCallWrapper()); | 318 const CallWrapper& call_wrapper = NullCallWrapper()); |
| 360 | 319 |
| 361 // Store the function for the given builtin in the target register. | 320 // Store the function for the given builtin in the target register. |
| 362 void GetBuiltinFunction(Register target, int native_context_index); | 321 void GetBuiltinFunction(Register target, int native_context_index); |
| 363 | 322 |
| 364 // Store the code object for the given builtin in the target register. | |
| 365 void GetBuiltinEntry(Register target, int native_context_index); | |
| 366 | 323 |
| 367 // Expression support | 324 // Expression support |
| 368 // Support for constant splitting. | 325 // Support for constant splitting. |
| 369 bool IsUnsafeImmediate(const Immediate& x); | 326 bool IsUnsafeImmediate(const Immediate& x); |
| 370 void SafeMove(Register dst, const Immediate& x); | 327 void SafeMove(Register dst, const Immediate& x); |
| 371 void SafePush(const Immediate& x); | 328 void SafePush(const Immediate& x); |
| 372 | 329 |
| 373 // Compare object type for heap object. | 330 // Compare object type for heap object. |
| 374 // Incoming register is heap_object and outgoing register is map. | 331 // Incoming register is heap_object and outgoing register is map. |
| 375 void CmpObjectType(Register heap_object, InstanceType type, Register map); | 332 void CmpObjectType(Register heap_object, InstanceType type, Register map); |
| 376 | 333 |
| 377 // Compare instance type for map. | 334 // Compare instance type for map. |
| 378 void CmpInstanceType(Register map, InstanceType type); | 335 void CmpInstanceType(Register map, InstanceType type); |
| 379 | 336 |
| 380 // Check if a map for a JSObject indicates that the object has fast elements. | 337 // Check if a map for a JSObject indicates that the object has fast elements. |
| 381 // Jump to the specified label if it does not. | 338 // Jump to the specified label if it does not. |
| 382 void CheckFastElements(Register map, | 339 void CheckFastElements(Register map, Label* fail, |
| 383 Label* fail, | |
| 384 Label::Distance distance = Label::kFar); | 340 Label::Distance distance = Label::kFar); |
| 385 | 341 |
| 386 // Check if a map for a JSObject indicates that the object can have both smi | 342 // Check if a map for a JSObject indicates that the object can have both smi |
| 387 // and HeapObject elements. Jump to the specified label if it does not. | 343 // and HeapObject elements. Jump to the specified label if it does not. |
| 388 void CheckFastObjectElements(Register map, | 344 void CheckFastObjectElements(Register map, Label* fail, |
| 389 Label* fail, | |
| 390 Label::Distance distance = Label::kFar); | 345 Label::Distance distance = Label::kFar); |
| 391 | 346 |
| 392 // Check if a map for a JSObject indicates that the object has fast smi only | 347 // Check if a map for a JSObject indicates that the object has fast smi only |
| 393 // elements. Jump to the specified label if it does not. | 348 // elements. Jump to the specified label if it does not. |
| 394 void CheckFastSmiElements(Register map, | 349 void CheckFastSmiElements(Register map, Label* fail, |
| 395 Label* fail, | |
| 396 Label::Distance distance = Label::kFar); | 350 Label::Distance distance = Label::kFar); |
| 397 | 351 |
| 398 // Check to see if maybe_number can be stored as a double in | 352 // Check to see if maybe_number can be stored as a double in |
| 399 // FastDoubleElements. If it can, store it at the index specified by key in | 353 // FastDoubleElements. If it can, store it at the index specified by key in |
| 400 // the FastDoubleElements array elements, otherwise jump to fail. | 354 // the FastDoubleElements array elements, otherwise jump to fail. |
| 401 void StoreNumberToDoubleElements(Register maybe_number, | 355 void StoreNumberToDoubleElements(Register maybe_number, Register elements, |
| 402 Register elements, | 356 Register key, Register scratch, Label* fail, |
| 403 Register key, | |
| 404 Register scratch, | |
| 405 Label* fail, | |
| 406 int offset = 0); | 357 int offset = 0); |
| 407 | 358 |
| 408 // Compare an object's map with the specified map. | 359 // Compare an object's map with the specified map. |
| 409 void CompareMap(Register obj, Handle<Map> map); | 360 void CompareMap(Register obj, Handle<Map> map); |
| 410 | 361 |
| 411 // Check if the map of an object is equal to a specified map and branch to | 362 // Check if the map of an object is equal to a specified map and branch to |
| 412 // label if not. Skip the smi check if not required (object is known to be a | 363 // label if not. Skip the smi check if not required (object is known to be a |
| 413 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match | 364 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match |
| 414 // against maps that are ElementsKind transition maps of the specified map. | 365 // against maps that are ElementsKind transition maps of the specified map. |
| 415 void CheckMap(Register obj, | 366 void CheckMap(Register obj, Handle<Map> map, Label* fail, |
| 416 Handle<Map> map, | |
| 417 Label* fail, | |
| 418 SmiCheckType smi_check_type); | 367 SmiCheckType smi_check_type); |
| 419 | 368 |
| 420 // Check if the map of an object is equal to a specified weak map and branch | 369 // Check if the map of an object is equal to a specified weak map and branch |
| 421 // to a specified target if equal. Skip the smi check if not required | 370 // to a specified target if equal. Skip the smi check if not required |
| 422 // (object is known to be a heap object) | 371 // (object is known to be a heap object) |
| 423 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, | 372 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, |
| 424 Handle<WeakCell> cell, Handle<Code> success, | 373 Handle<WeakCell> cell, Handle<Code> success, |
| 425 SmiCheckType smi_check_type); | 374 SmiCheckType smi_check_type); |
| 426 | 375 |
| 427 // Check if the object in register heap_object is a string. Afterwards the | 376 // Check if the object in register heap_object is a string. Afterwards the |
| 428 // register map contains the object map and the register instance_type | 377 // register map contains the object map and the register instance_type |
| 429 // contains the instance_type. The registers map and instance_type can be the | 378 // contains the instance_type. The registers map and instance_type can be the |
| 430 // same in which case it contains the instance type afterwards. Either of the | 379 // same in which case it contains the instance type afterwards. Either of the |
| 431 // registers map and instance_type can be the same as heap_object. | 380 // registers map and instance_type can be the same as heap_object. |
| 432 Condition IsObjectStringType(Register heap_object, | 381 Condition IsObjectStringType(Register heap_object, Register map, |
| 433 Register map, | |
| 434 Register instance_type); | 382 Register instance_type); |
| 435 | 383 |
| 436 // Check if the object in register heap_object is a name. Afterwards the | 384 // Check if the object in register heap_object is a name. Afterwards the |
| 437 // register map contains the object map and the register instance_type | 385 // register map contains the object map and the register instance_type |
| 438 // contains the instance_type. The registers map and instance_type can be the | 386 // contains the instance_type. The registers map and instance_type can be the |
| 439 // same in which case it contains the instance type afterwards. Either of the | 387 // same in which case it contains the instance type afterwards. Either of the |
| 440 // registers map and instance_type can be the same as heap_object. | 388 // registers map and instance_type can be the same as heap_object. |
| 441 Condition IsObjectNameType(Register heap_object, | 389 Condition IsObjectNameType(Register heap_object, Register map, |
| 442 Register map, | |
| 443 Register instance_type); | 390 Register instance_type); |
| 444 | 391 |
| 445 // FCmp is similar to integer cmp, but requires unsigned | 392 // FCmp is similar to integer cmp, but requires unsigned |
| 446 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). | 393 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). |
| 447 void FCmp(); | 394 void FCmp(); |
| 448 void FXamMinusZero(); | 395 void FXamMinusZero(); |
| 449 void FXamSign(); | 396 void FXamSign(); |
| 450 void X87CheckIA(); | 397 void X87CheckIA(); |
| 451 void X87SetRC(int rc); | 398 void X87SetRC(int rc); |
| 452 void X87SetFPUCW(int cw); | 399 void X87SetFPUCW(int cw); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 481 STATIC_ASSERT(kSmiTag == 0); | 428 STATIC_ASSERT(kSmiTag == 0); |
| 482 j(not_carry, is_smi); | 429 j(not_carry, is_smi); |
| 483 } | 430 } |
| 484 | 431 |
| 485 void LoadUint32NoSSE2(Register src) { | 432 void LoadUint32NoSSE2(Register src) { |
| 486 LoadUint32NoSSE2(Operand(src)); | 433 LoadUint32NoSSE2(Operand(src)); |
| 487 } | 434 } |
| 488 void LoadUint32NoSSE2(const Operand& src); | 435 void LoadUint32NoSSE2(const Operand& src); |
| 489 | 436 |
| 490 // Jump the register contains a smi. | 437 // Jump the register contains a smi. |
| 491 inline void JumpIfSmi(Register value, | 438 inline void JumpIfSmi(Register value, Label* smi_label, |
| 492 Label* smi_label, | |
| 493 Label::Distance distance = Label::kFar) { | 439 Label::Distance distance = Label::kFar) { |
| 494 test(value, Immediate(kSmiTagMask)); | 440 test(value, Immediate(kSmiTagMask)); |
| 495 j(zero, smi_label, distance); | 441 j(zero, smi_label, distance); |
| 496 } | 442 } |
| 497 // Jump if the operand is a smi. | 443 // Jump if the operand is a smi. |
| 498 inline void JumpIfSmi(Operand value, | 444 inline void JumpIfSmi(Operand value, Label* smi_label, |
| 499 Label* smi_label, | |
| 500 Label::Distance distance = Label::kFar) { | 445 Label::Distance distance = Label::kFar) { |
| 501 test(value, Immediate(kSmiTagMask)); | 446 test(value, Immediate(kSmiTagMask)); |
| 502 j(zero, smi_label, distance); | 447 j(zero, smi_label, distance); |
| 503 } | 448 } |
| 504 // Jump if register contain a non-smi. | 449 // Jump if register contain a non-smi. |
| 505 inline void JumpIfNotSmi(Register value, | 450 inline void JumpIfNotSmi(Register value, Label* not_smi_label, |
| 506 Label* not_smi_label, | |
| 507 Label::Distance distance = Label::kFar) { | 451 Label::Distance distance = Label::kFar) { |
| 508 test(value, Immediate(kSmiTagMask)); | 452 test(value, Immediate(kSmiTagMask)); |
| 509 j(not_zero, not_smi_label, distance); | 453 j(not_zero, not_smi_label, distance); |
| 510 } | 454 } |
| 511 | 455 |
| 512 void LoadInstanceDescriptors(Register map, Register descriptors); | 456 void LoadInstanceDescriptors(Register map, Register descriptors); |
| 513 void EnumLength(Register dst, Register map); | 457 void EnumLength(Register dst, Register map); |
| 514 void NumberOfOwnDescriptors(Register dst, Register map); | 458 void NumberOfOwnDescriptors(Register dst, Register map); |
| 515 void LoadAccessor(Register dst, Register holder, int accessor_index, | 459 void LoadAccessor(Register dst, Register holder, int accessor_index, |
| 516 AccessorComponent accessor); | 460 AccessorComponent accessor); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 | 513 |
| 570 // Unlink the stack handler on top of the stack from the stack handler chain. | 514 // Unlink the stack handler on top of the stack from the stack handler chain. |
| 571 void PopStackHandler(); | 515 void PopStackHandler(); |
| 572 | 516 |
| 573 // --------------------------------------------------------------------------- | 517 // --------------------------------------------------------------------------- |
| 574 // Inline caching support | 518 // Inline caching support |
| 575 | 519 |
| 576 // Generate code for checking access rights - used for security checks | 520 // Generate code for checking access rights - used for security checks |
| 577 // on access to global objects across environments. The holder register | 521 // on access to global objects across environments. The holder register |
| 578 // is left untouched, but the scratch register is clobbered. | 522 // is left untouched, but the scratch register is clobbered. |
| 579 void CheckAccessGlobalProxy(Register holder_reg, | 523 void CheckAccessGlobalProxy(Register holder_reg, Register scratch1, |
| 580 Register scratch1, | 524 Register scratch2, Label* miss); |
| 581 Register scratch2, | |
| 582 Label* miss); | |
| 583 | 525 |
| 584 void GetNumberHash(Register r0, Register scratch); | 526 void GetNumberHash(Register r0, Register scratch); |
| 585 | 527 |
| 586 void LoadFromNumberDictionary(Label* miss, | 528 void LoadFromNumberDictionary(Label* miss, Register elements, Register key, |
| 587 Register elements, | 529 Register r0, Register r1, Register r2, |
| 588 Register key, | |
| 589 Register r0, | |
| 590 Register r1, | |
| 591 Register r2, | |
| 592 Register result); | 530 Register result); |
| 593 | 531 |
| 594 | |
| 595 // --------------------------------------------------------------------------- | 532 // --------------------------------------------------------------------------- |
| 596 // Allocation support | 533 // Allocation support |
| 597 | 534 |
| 598 // Allocate an object in new space or old space. If the given space | 535 // Allocate an object in new space or old space. If the given space |
| 599 // is exhausted control continues at the gc_required label. The allocated | 536 // is exhausted control continues at the gc_required label. The allocated |
| 600 // object is returned in result and end of the new object is returned in | 537 // object is returned in result and end of the new object is returned in |
| 601 // result_end. The register scratch can be passed as no_reg in which case | 538 // result_end. The register scratch can be passed as no_reg in which case |
| 602 // an additional object reference will be added to the reloc info. The | 539 // an additional object reference will be added to the reloc info. The |
| 603 // returned pointers in result and result_end have not yet been tagged as | 540 // returned pointers in result and result_end have not yet been tagged as |
| 604 // heap objects. If result_contains_top_on_entry is true the content of | 541 // heap objects. If result_contains_top_on_entry is true the content of |
| 605 // result is known to be the allocation top on entry (could be result_end | 542 // result is known to be the allocation top on entry (could be result_end |
| 606 // from a previous call). If result_contains_top_on_entry is true scratch | 543 // from a previous call). If result_contains_top_on_entry is true scratch |
| 607 // should be no_reg as it is never used. | 544 // should be no_reg as it is never used. |
| 608 void Allocate(int object_size, | 545 void Allocate(int object_size, Register result, Register result_end, |
| 609 Register result, | 546 Register scratch, Label* gc_required, AllocationFlags flags); |
| 610 Register result_end, | |
| 611 Register scratch, | |
| 612 Label* gc_required, | |
| 613 AllocationFlags flags); | |
| 614 | 547 |
| 615 void Allocate(int header_size, | 548 void Allocate(int header_size, ScaleFactor element_size, |
| 616 ScaleFactor element_size, | 549 Register element_count, RegisterValueType element_count_type, |
| 617 Register element_count, | 550 Register result, Register result_end, Register scratch, |
| 618 RegisterValueType element_count_type, | 551 Label* gc_required, AllocationFlags flags); |
| 619 Register result, | |
| 620 Register result_end, | |
| 621 Register scratch, | |
| 622 Label* gc_required, | |
| 623 AllocationFlags flags); | |
| 624 | 552 |
| 625 void Allocate(Register object_size, | 553 void Allocate(Register object_size, Register result, Register result_end, |
| 626 Register result, | 554 Register scratch, Label* gc_required, AllocationFlags flags); |
| 627 Register result_end, | |
| 628 Register scratch, | |
| 629 Label* gc_required, | |
| 630 AllocationFlags flags); | |
| 631 | 555 |
| 632 // Allocate a heap number in new space with undefined value. The | 556 // Allocate a heap number in new space with undefined value. The |
| 633 // register scratch2 can be passed as no_reg; the others must be | 557 // register scratch2 can be passed as no_reg; the others must be |
| 634 // valid registers. Returns tagged pointer in result register, or | 558 // valid registers. Returns tagged pointer in result register, or |
| 635 // jumps to gc_required if new space is full. | 559 // jumps to gc_required if new space is full. |
| 636 void AllocateHeapNumber(Register result, | 560 void AllocateHeapNumber(Register result, Register scratch1, Register scratch2, |
| 637 Register scratch1, | 561 Label* gc_required, MutableMode mode = IMMUTABLE); |
| 638 Register scratch2, | |
| 639 Label* gc_required, | |
| 640 MutableMode mode = IMMUTABLE); | |
| 641 | 562 |
| 642 // Allocate a sequential string. All the header fields of the string object | 563 // Allocate a sequential string. All the header fields of the string object |
| 643 // are initialized. | 564 // are initialized. |
| 644 void AllocateTwoByteString(Register result, | 565 void AllocateTwoByteString(Register result, Register length, |
| 645 Register length, | 566 Register scratch1, Register scratch2, |
| 646 Register scratch1, | 567 Register scratch3, Label* gc_required); |
| 647 Register scratch2, | |
| 648 Register scratch3, | |
| 649 Label* gc_required); | |
| 650 void AllocateOneByteString(Register result, Register length, | 568 void AllocateOneByteString(Register result, Register length, |
| 651 Register scratch1, Register scratch2, | 569 Register scratch1, Register scratch2, |
| 652 Register scratch3, Label* gc_required); | 570 Register scratch3, Label* gc_required); |
| 653 void AllocateOneByteString(Register result, int length, Register scratch1, | 571 void AllocateOneByteString(Register result, int length, Register scratch1, |
| 654 Register scratch2, Label* gc_required); | 572 Register scratch2, Label* gc_required); |
| 655 | 573 |
| 656 // Allocate a raw cons string object. Only the map field of the result is | 574 // Allocate a raw cons string object. Only the map field of the result is |
| 657 // initialized. | 575 // initialized. |
| 658 void AllocateTwoByteConsString(Register result, | 576 void AllocateTwoByteConsString(Register result, Register scratch1, |
| 659 Register scratch1, | 577 Register scratch2, Label* gc_required); |
| 660 Register scratch2, | |
| 661 Label* gc_required); | |
| 662 void AllocateOneByteConsString(Register result, Register scratch1, | 578 void AllocateOneByteConsString(Register result, Register scratch1, |
| 663 Register scratch2, Label* gc_required); | 579 Register scratch2, Label* gc_required); |
| 664 | 580 |
| 665 // Allocate a raw sliced string object. Only the map field of the result is | 581 // Allocate a raw sliced string object. Only the map field of the result is |
| 666 // initialized. | 582 // initialized. |
| 667 void AllocateTwoByteSlicedString(Register result, | 583 void AllocateTwoByteSlicedString(Register result, Register scratch1, |
| 668 Register scratch1, | 584 Register scratch2, Label* gc_required); |
| 669 Register scratch2, | |
| 670 Label* gc_required); | |
| 671 void AllocateOneByteSlicedString(Register result, Register scratch1, | 585 void AllocateOneByteSlicedString(Register result, Register scratch1, |
| 672 Register scratch2, Label* gc_required); | 586 Register scratch2, Label* gc_required); |
| 673 | 587 |
| 674 // Copy memory, byte-by-byte, from source to destination. Not optimized for | 588 // Copy memory, byte-by-byte, from source to destination. Not optimized for |
| 675 // long or aligned copies. | 589 // long or aligned copies. |
| 676 // The contents of index and scratch are destroyed. | 590 // The contents of index and scratch are destroyed. |
| 677 void CopyBytes(Register source, | 591 void CopyBytes(Register source, Register destination, Register length, |
| 678 Register destination, | |
| 679 Register length, | |
| 680 Register scratch); | 592 Register scratch); |
| 681 | 593 |
| 682 // Initialize fields with filler values. Fields starting at |current_address| | 594 // Initialize fields with filler values. Fields starting at |current_address| |
| 683 // not including |end_address| are overwritten with the value in |filler|. At | 595 // not including |end_address| are overwritten with the value in |filler|. At |
| 684 // the end the loop, |current_address| takes the value of |end_address|. | 596 // the end the loop, |current_address| takes the value of |end_address|. |
| 685 void InitializeFieldsWithFiller(Register current_address, | 597 void InitializeFieldsWithFiller(Register current_address, |
| 686 Register end_address, Register filler); | 598 Register end_address, Register filler); |
| 687 | 599 |
| 688 // --------------------------------------------------------------------------- | 600 // --------------------------------------------------------------------------- |
| 689 // Support functions. | 601 // Support functions. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles); | 655 CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles); |
| 744 } | 656 } |
| 745 | 657 |
| 746 // Convenience function: call an external reference. | 658 // Convenience function: call an external reference. |
| 747 void CallExternalReference(ExternalReference ref, int num_arguments); | 659 void CallExternalReference(ExternalReference ref, int num_arguments); |
| 748 | 660 |
| 749 // Tail call of a runtime routine (jump). | 661 // Tail call of a runtime routine (jump). |
| 750 // Like JumpToExternalReference, but also takes care of passing the number | 662 // Like JumpToExternalReference, but also takes care of passing the number |
| 751 // of parameters. | 663 // of parameters. |
| 752 void TailCallExternalReference(const ExternalReference& ext, | 664 void TailCallExternalReference(const ExternalReference& ext, |
| 753 int num_arguments, | 665 int num_arguments, int result_size); |
| 754 int result_size); | |
| 755 | 666 |
| 756 // Convenience function: tail call a runtime routine (jump). | 667 // Convenience function: tail call a runtime routine (jump). |
| 757 void TailCallRuntime(Runtime::FunctionId fid, | 668 void TailCallRuntime(Runtime::FunctionId fid, int num_arguments, |
| 758 int num_arguments, | |
| 759 int result_size); | 669 int result_size); |
| 760 | 670 |
| 761 // Before calling a C-function from generated code, align arguments on stack. | 671 // Before calling a C-function from generated code, align arguments on stack. |
| 762 // After aligning the frame, arguments must be stored in esp[0], esp[4], | 672 // After aligning the frame, arguments must be stored in esp[0], esp[4], |
| 763 // etc., not pushed. The argument count assumes all arguments are word sized. | 673 // etc., not pushed. The argument count assumes all arguments are word sized. |
| 764 // Some compilers/platforms require the stack to be aligned when calling | 674 // Some compilers/platforms require the stack to be aligned when calling |
| 765 // C++ code. | 675 // C++ code. |
| 766 // Needs a scratch register to do some arithmetic. This register will be | 676 // Needs a scratch register to do some arithmetic. This register will be |
| 767 // trashed. | 677 // trashed. |
| 768 void PrepareCallCFunction(int num_arguments, Register scratch); | 678 void PrepareCallCFunction(int num_arguments, Register scratch); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 | 752 |
| 843 // --------------------------------------------------------------------------- | 753 // --------------------------------------------------------------------------- |
| 844 // StatsCounter support | 754 // StatsCounter support |
| 845 | 755 |
| 846 void SetCounter(StatsCounter* counter, int value); | 756 void SetCounter(StatsCounter* counter, int value); |
| 847 void IncrementCounter(StatsCounter* counter, int value); | 757 void IncrementCounter(StatsCounter* counter, int value); |
| 848 void DecrementCounter(StatsCounter* counter, int value); | 758 void DecrementCounter(StatsCounter* counter, int value); |
| 849 void IncrementCounter(Condition cc, StatsCounter* counter, int value); | 759 void IncrementCounter(Condition cc, StatsCounter* counter, int value); |
| 850 void DecrementCounter(Condition cc, StatsCounter* counter, int value); | 760 void DecrementCounter(Condition cc, StatsCounter* counter, int value); |
| 851 | 761 |
| 852 | |
| 853 // --------------------------------------------------------------------------- | 762 // --------------------------------------------------------------------------- |
| 854 // Debugging | 763 // Debugging |
| 855 | 764 |
| 856 // Calls Abort(msg) if the condition cc is not satisfied. | 765 // Calls Abort(msg) if the condition cc is not satisfied. |
| 857 // Use --debug_code to enable. | 766 // Use --debug_code to enable. |
| 858 void Assert(Condition cc, BailoutReason reason); | 767 void Assert(Condition cc, BailoutReason reason); |
| 859 | 768 |
| 860 void AssertFastElements(Register elements); | 769 void AssertFastElements(Register elements); |
| 861 | 770 |
| 862 // Like Assert(), but always enabled. | 771 // Like Assert(), but always enabled. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 893 | 802 |
| 894 // Checks if the given register or operand is a unique name | 803 // Checks if the given register or operand is a unique name |
| 895 void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name, | 804 void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name, |
| 896 Label::Distance distance = Label::kFar) { | 805 Label::Distance distance = Label::kFar) { |
| 897 JumpIfNotUniqueNameInstanceType(Operand(reg), not_unique_name, distance); | 806 JumpIfNotUniqueNameInstanceType(Operand(reg), not_unique_name, distance); |
| 898 } | 807 } |
| 899 | 808 |
| 900 void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name, | 809 void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name, |
| 901 Label::Distance distance = Label::kFar); | 810 Label::Distance distance = Label::kFar); |
| 902 | 811 |
| 903 void EmitSeqStringSetCharCheck(Register string, | 812 void EmitSeqStringSetCharCheck(Register string, Register index, |
| 904 Register index, | 813 Register value, uint32_t encoding_mask); |
| 905 Register value, | |
| 906 uint32_t encoding_mask); | |
| 907 | 814 |
| 908 static int SafepointRegisterStackIndex(Register reg) { | 815 static int SafepointRegisterStackIndex(Register reg) { |
| 909 return SafepointRegisterStackIndex(reg.code()); | 816 return SafepointRegisterStackIndex(reg.code()); |
| 910 } | 817 } |
| 911 | 818 |
| 912 // Load the type feedback vector from a JavaScript frame. | 819 // Load the type feedback vector from a JavaScript frame. |
| 913 void EmitLoadTypeFeedbackVector(Register vector); | 820 void EmitLoadTypeFeedbackVector(Register vector); |
| 914 | 821 |
| 915 // Activation support. | 822 // Activation support. |
| 916 void EnterFrame(StackFrame::Type type); | 823 void EnterFrame(StackFrame::Type type); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 // This handle will be patched with the code object on installation. | 858 // This handle will be patched with the code object on installation. |
| 952 Handle<Object> code_object_; | 859 Handle<Object> code_object_; |
| 953 | 860 |
| 954 // Helper functions for generating invokes. | 861 // Helper functions for generating invokes. |
| 955 void InvokePrologue(const ParameterCount& expected, | 862 void InvokePrologue(const ParameterCount& expected, |
| 956 const ParameterCount& actual, Label* done, | 863 const ParameterCount& actual, Label* done, |
| 957 bool* definitely_mismatches, InvokeFlag flag, | 864 bool* definitely_mismatches, InvokeFlag flag, |
| 958 Label::Distance done_distance, | 865 Label::Distance done_distance, |
| 959 const CallWrapper& call_wrapper); | 866 const CallWrapper& call_wrapper); |
| 960 | 867 |
| 868 void FloodFunctionIfStepping(Register fun, Register new_target, |
| 869 const ParameterCount& expected, |
| 870 const ParameterCount& actual); |
| 871 |
| 961 void EnterExitFramePrologue(); | 872 void EnterExitFramePrologue(); |
| 962 void EnterExitFrameEpilogue(int argc, bool save_doubles); | 873 void EnterExitFrameEpilogue(int argc, bool save_doubles); |
| 963 | 874 |
| 964 void LeaveExitFrameEpilogue(bool restore_context); | 875 void LeaveExitFrameEpilogue(bool restore_context); |
| 965 | 876 |
| 966 // Allocation support helpers. | 877 // Allocation support helpers. |
| 967 void LoadAllocationTopHelper(Register result, | 878 void LoadAllocationTopHelper(Register result, Register scratch, |
| 968 Register scratch, | |
| 969 AllocationFlags flags); | 879 AllocationFlags flags); |
| 970 | 880 |
| 971 void UpdateAllocationTopHelper(Register result_end, | 881 void UpdateAllocationTopHelper(Register result_end, Register scratch, |
| 972 Register scratch, | |
| 973 AllocationFlags flags); | 882 AllocationFlags flags); |
| 974 | 883 |
| 975 // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. | 884 // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. |
| 976 void InNewSpace(Register object, | 885 void InNewSpace(Register object, Register scratch, Condition cc, |
| 977 Register scratch, | |
| 978 Condition cc, | |
| 979 Label* condition_met, | 886 Label* condition_met, |
| 980 Label::Distance condition_met_distance = Label::kFar); | 887 Label::Distance condition_met_distance = Label::kFar); |
| 981 | 888 |
| 982 // Helper for finding the mark bits for an address. Afterwards, the | 889 // Helper for finding the mark bits for an address. Afterwards, the |
| 983 // bitmap register points at the word with the mark bits and the mask | 890 // bitmap register points at the word with the mark bits and the mask |
| 984 // the position of the first bit. Uses ecx as scratch and leaves addr_reg | 891 // the position of the first bit. Uses ecx as scratch and leaves addr_reg |
| 985 // unchanged. | 892 // unchanged. |
| 986 inline void GetMarkBits(Register addr_reg, | 893 inline void GetMarkBits(Register addr_reg, Register bitmap_reg, |
| 987 Register bitmap_reg, | |
| 988 Register mask_reg); | 894 Register mask_reg); |
| 989 | 895 |
| 990 // Compute memory operands for safepoint stack slots. | 896 // Compute memory operands for safepoint stack slots. |
| 991 Operand SafepointRegisterSlot(Register reg); | 897 Operand SafepointRegisterSlot(Register reg); |
| 992 static int SafepointRegisterStackIndex(int reg_code); | 898 static int SafepointRegisterStackIndex(int reg_code); |
| 993 | 899 |
| 994 // Needs access to SafepointRegisterStackIndex for compiled frame | 900 // Needs access to SafepointRegisterStackIndex for compiled frame |
| 995 // traversal. | 901 // traversal. |
| 996 friend class StandardFrame; | 902 friend class StandardFrame; |
| 997 }; | 903 }; |
| 998 | 904 |
| 999 | |
| 1000 // The code patcher is used to patch (typically) small parts of code e.g. for | 905 // The code patcher is used to patch (typically) small parts of code e.g. for |
| 1001 // debugging and other types of instrumentation. When using the code patcher | 906 // debugging and other types of instrumentation. When using the code patcher |
| 1002 // the exact number of bytes specified must be emitted. Is not legal to emit | 907 // the exact number of bytes specified must be emitted. Is not legal to emit |
| 1003 // relocation information. If any of these constraints are violated it causes | 908 // relocation information. If any of these constraints are violated it causes |
| 1004 // an assertion. | 909 // an assertion. |
| 1005 class CodePatcher { | 910 class CodePatcher { |
| 1006 public: | 911 public: |
| 1007 CodePatcher(byte* address, int size); | 912 CodePatcher(byte* address, int size); |
| 1008 ~CodePatcher(); | 913 ~CodePatcher(); |
| 1009 | 914 |
| 1010 // Macro assembler to emit code. | 915 // Macro assembler to emit code. |
| 1011 MacroAssembler* masm() { return &masm_; } | 916 MacroAssembler* masm() { return &masm_; } |
| 1012 | 917 |
| 1013 private: | 918 private: |
| 1014 byte* address_; // The address of the code being patched. | 919 byte* address_; // The address of the code being patched. |
| 1015 int size_; // Number of bytes of the expected patch size. | 920 int size_; // Number of bytes of the expected patch size. |
| 1016 MacroAssembler masm_; // Macro assembler used to generate the code. | 921 MacroAssembler masm_; // Macro assembler used to generate the code. |
| 1017 }; | 922 }; |
| 1018 | 923 |
| 1019 | |
| 1020 // ----------------------------------------------------------------------------- | 924 // ----------------------------------------------------------------------------- |
| 1021 // Static helper functions. | 925 // Static helper functions. |
| 1022 | 926 |
| 1023 // Generate an Operand for loading a field from an object. | 927 // Generate an Operand for loading a field from an object. |
| 1024 inline Operand FieldOperand(Register object, int offset) { | 928 inline Operand FieldOperand(Register object, int offset) { |
| 1025 return Operand(object, offset - kHeapObjectTag); | 929 return Operand(object, offset - kHeapObjectTag); |
| 1026 } | 930 } |
| 1027 | 931 |
| 1028 | |
| 1029 // Generate an Operand for loading an indexed field from an object. | 932 // Generate an Operand for loading an indexed field from an object. |
| 1030 inline Operand FieldOperand(Register object, | 933 inline Operand FieldOperand(Register object, Register index, ScaleFactor scale, |
| 1031 Register index, | |
| 1032 ScaleFactor scale, | |
| 1033 int offset) { | 934 int offset) { |
| 1034 return Operand(object, index, scale, offset - kHeapObjectTag); | 935 return Operand(object, index, scale, offset - kHeapObjectTag); |
| 1035 } | 936 } |
| 1036 | 937 |
| 1037 | 938 inline Operand FixedArrayElementOperand(Register array, Register index_as_smi, |
| 1038 inline Operand FixedArrayElementOperand(Register array, | |
| 1039 Register index_as_smi, | |
| 1040 int additional_offset = 0) { | 939 int additional_offset = 0) { |
| 1041 int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize; | 940 int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize; |
| 1042 return FieldOperand(array, index_as_smi, times_half_pointer_size, offset); | 941 return FieldOperand(array, index_as_smi, times_half_pointer_size, offset); |
| 1043 } | 942 } |
| 1044 | 943 |
| 1045 | |
| 1046 inline Operand ContextOperand(Register context, int index) { | 944 inline Operand ContextOperand(Register context, int index) { |
| 1047 return Operand(context, Context::SlotOffset(index)); | 945 return Operand(context, Context::SlotOffset(index)); |
| 1048 } | 946 } |
| 1049 | 947 |
| 1050 | |
| 1051 inline Operand ContextOperand(Register context, Register index) { | 948 inline Operand ContextOperand(Register context, Register index) { |
| 1052 return Operand(context, index, times_pointer_size, Context::SlotOffset(0)); | 949 return Operand(context, index, times_pointer_size, Context::SlotOffset(0)); |
| 1053 } | 950 } |
| 1054 | 951 |
| 1055 | |
| 1056 inline Operand GlobalObjectOperand() { | 952 inline Operand GlobalObjectOperand() { |
| 1057 return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX); | 953 return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX); |
| 1058 } | 954 } |
| 1059 | 955 |
| 1060 | |
| 1061 #ifdef GENERATED_CODE_COVERAGE | 956 #ifdef GENERATED_CODE_COVERAGE |
| 1062 extern void LogGeneratedCodeCoverage(const char* file_line); | 957 extern void LogGeneratedCodeCoverage(const char* file_line); |
| 1063 #define CODE_COVERAGE_STRINGIFY(x) #x | 958 #define CODE_COVERAGE_STRINGIFY(x) #x |
| 1064 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) | 959 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) |
| 1065 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) | 960 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) |
| 1066 #define ACCESS_MASM(masm) { \ | 961 #define ACCESS_MASM(masm) { \ |
| 1067 byte* ia32_coverage_function = \ | 962 byte* ia32_coverage_function = \ |
| 1068 reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \ | 963 reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \ |
| 1069 masm->pushfd(); \ | 964 masm->pushfd(); \ |
| 1070 masm->pushad(); \ | 965 masm->pushad(); \ |
| 1071 masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ | 966 masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ |
| 1072 masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \ | 967 masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \ |
| 1073 masm->pop(eax); \ | 968 masm->pop(eax); \ |
| 1074 masm->popad(); \ | 969 masm->popad(); \ |
| 1075 masm->popfd(); \ | 970 masm->popfd(); \ |
| 1076 } \ | 971 } \ |
| 1077 masm-> | 972 masm-> |
| 1078 #else | 973 #else |
| 1079 #define ACCESS_MASM(masm) masm-> | 974 #define ACCESS_MASM(masm) masm-> |
| 1080 #endif | 975 #endif |
| 1081 | 976 |
| 1082 | |
| 1083 } // namespace internal | 977 } // namespace internal |
| 1084 } // namespace v8 | 978 } // namespace v8 |
| 1085 | 979 |
| 1086 #endif // V8_X87_MACRO_ASSEMBLER_X87_H_ | 980 #endif // V8_X87_MACRO_ASSEMBLER_X87_H_ |
| OLD | NEW |