| 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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 SaveFPRegsMode save_fp, | 190 SaveFPRegsMode save_fp, |
| 191 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | 191 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 192 SmiCheck smi_check = INLINE_SMI_CHECK, | 192 SmiCheck smi_check = INLINE_SMI_CHECK, |
| 193 PointersToHereCheck pointers_to_here_check_for_value = | 193 PointersToHereCheck pointers_to_here_check_for_value = |
| 194 kPointersToHereMaybeInteresting) { | 194 kPointersToHereMaybeInteresting) { |
| 195 RecordWriteField(context, offset + kHeapObjectTag, value, scratch, save_fp, | 195 RecordWriteField(context, offset + kHeapObjectTag, value, scratch, save_fp, |
| 196 remembered_set_action, smi_check, | 196 remembered_set_action, smi_check, |
| 197 pointers_to_here_check_for_value); | 197 pointers_to_here_check_for_value); |
| 198 } | 198 } |
| 199 | 199 |
| 200 // Notify the garbage collector that we wrote a pointer into a fixed array. | |
| 201 // |array| is the array being stored into, |value| is the | |
| 202 // object being stored. |index| is the array index represented as a | |
| 203 // Smi. All registers are clobbered by the operation RecordWriteArray | |
| 204 // filters out smis so it does not update the write barrier if the | |
| 205 // value is a smi. | |
| 206 void RecordWriteArray( | |
| 207 Register array, Register value, Register index, SaveFPRegsMode save_fp, | |
| 208 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | |
| 209 SmiCheck smi_check = INLINE_SMI_CHECK, | |
| 210 PointersToHereCheck pointers_to_here_check_for_value = | |
| 211 kPointersToHereMaybeInteresting); | |
| 212 | |
| 213 // For page containing |object| mark region covering |address| | 200 // For page containing |object| mark region covering |address| |
| 214 // dirty. |object| is the object being stored into, |value| is the | 201 // dirty. |object| is the object being stored into, |value| is the |
| 215 // object being stored. The address and value registers are clobbered by the | 202 // object being stored. The address and value registers are clobbered by the |
| 216 // operation. RecordWrite filters out smis so it does not update the | 203 // operation. RecordWrite filters out smis so it does not update the |
| 217 // write barrier if the value is a smi. | 204 // write barrier if the value is a smi. |
| 218 void RecordWrite( | 205 void RecordWrite( |
| 219 Register object, Register address, Register value, SaveFPRegsMode save_fp, | 206 Register object, Register address, Register value, SaveFPRegsMode save_fp, |
| 220 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | 207 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 221 SmiCheck smi_check = INLINE_SMI_CHECK, | 208 SmiCheck smi_check = INLINE_SMI_CHECK, |
| 222 PointersToHereCheck pointers_to_here_check_for_value = | 209 PointersToHereCheck pointers_to_here_check_for_value = |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 | 286 |
| 300 void CmpObject(Register reg, Handle<Object> object) { | 287 void CmpObject(Register reg, Handle<Object> object) { |
| 301 AllowDeferredHandleDereference heap_object_check; | 288 AllowDeferredHandleDereference heap_object_check; |
| 302 if (object->IsHeapObject()) { | 289 if (object->IsHeapObject()) { |
| 303 CmpHeapObject(reg, Handle<HeapObject>::cast(object)); | 290 CmpHeapObject(reg, Handle<HeapObject>::cast(object)); |
| 304 } else { | 291 } else { |
| 305 cmp(reg, Immediate(object)); | 292 cmp(reg, Immediate(object)); |
| 306 } | 293 } |
| 307 } | 294 } |
| 308 | 295 |
| 309 void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch); | |
| 310 void GetWeakValue(Register value, Handle<WeakCell> cell); | 296 void GetWeakValue(Register value, Handle<WeakCell> cell); |
| 311 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); | 297 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); |
| 312 | 298 |
| 313 // --------------------------------------------------------------------------- | 299 // --------------------------------------------------------------------------- |
| 314 // JavaScript invokes | 300 // JavaScript invokes |
| 315 | 301 |
| 316 // Removes current frame and its arguments from the stack preserving | 302 // Removes current frame and its arguments from the stack preserving |
| 317 // the arguments and a return address pushed to the stack for the next call. | 303 // the arguments and a return address pushed to the stack for the next call. |
| 318 // |ra_state| defines whether return address is already pushed to stack or | 304 // |ra_state| defines whether return address is already pushed to stack or |
| 319 // not. Both |callee_args_count| and |caller_args_count_reg| do not include | 305 // not. Both |callee_args_count| and |caller_args_count_reg| do not include |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 // Compare an object's map with the specified map. | 363 // Compare an object's map with the specified map. |
| 378 void CompareMap(Register obj, Handle<Map> map); | 364 void CompareMap(Register obj, Handle<Map> map); |
| 379 | 365 |
| 380 // Check if the map of an object is equal to a specified map and branch to | 366 // Check if the map of an object is equal to a specified map and branch to |
| 381 // label if not. Skip the smi check if not required (object is known to be a | 367 // label if not. Skip the smi check if not required (object is known to be a |
| 382 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match | 368 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match |
| 383 // against maps that are ElementsKind transition maps of the specified map. | 369 // against maps that are ElementsKind transition maps of the specified map. |
| 384 void CheckMap(Register obj, Handle<Map> map, Label* fail, | 370 void CheckMap(Register obj, Handle<Map> map, Label* fail, |
| 385 SmiCheckType smi_check_type); | 371 SmiCheckType smi_check_type); |
| 386 | 372 |
| 387 // Check if the map of an object is equal to a specified weak map and branch | |
| 388 // to a specified target if equal. Skip the smi check if not required | |
| 389 // (object is known to be a heap object) | |
| 390 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, | |
| 391 Handle<WeakCell> cell, Handle<Code> success, | |
| 392 SmiCheckType smi_check_type); | |
| 393 | |
| 394 // Check if the object in register heap_object is a string. Afterwards the | 373 // Check if the object in register heap_object is a string. Afterwards the |
| 395 // register map contains the object map and the register instance_type | 374 // register map contains the object map and the register instance_type |
| 396 // contains the instance_type. The registers map and instance_type can be the | 375 // contains the instance_type. The registers map and instance_type can be the |
| 397 // same in which case it contains the instance type afterwards. Either of the | 376 // same in which case it contains the instance type afterwards. Either of the |
| 398 // registers map and instance_type can be the same as heap_object. | 377 // registers map and instance_type can be the same as heap_object. |
| 399 Condition IsObjectStringType(Register heap_object, Register map, | 378 Condition IsObjectStringType(Register heap_object, Register map, |
| 400 Register instance_type); | 379 Register instance_type); |
| 401 | 380 |
| 402 // Check if the object in register heap_object is a name. Afterwards the | |
| 403 // register map contains the object map and the register instance_type | |
| 404 // contains the instance_type. The registers map and instance_type can be the | |
| 405 // same in which case it contains the instance type afterwards. Either of the | |
| 406 // registers map and instance_type can be the same as heap_object. | |
| 407 Condition IsObjectNameType(Register heap_object, Register map, | |
| 408 Register instance_type); | |
| 409 | |
| 410 // FCmp is similar to integer cmp, but requires unsigned | 381 // FCmp is similar to integer cmp, but requires unsigned |
| 411 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). | 382 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). |
| 412 void FCmp(); | 383 void FCmp(); |
| 413 void FXamMinusZero(); | 384 void FXamMinusZero(); |
| 414 void FXamSign(); | 385 void FXamSign(); |
| 415 void X87CheckIA(); | 386 void X87CheckIA(); |
| 416 void X87SetRC(int rc); | 387 void X87SetRC(int rc); |
| 417 void X87SetFPUCW(int cw); | 388 void X87SetFPUCW(int cw); |
| 418 | 389 |
| 419 void ClampUint8(Register reg); | 390 void ClampUint8(Register reg); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0); | 487 STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0); |
| 517 STATIC_ASSERT(kSmiTag == 0); | 488 STATIC_ASSERT(kSmiTag == 0); |
| 518 if (shift < kSmiTagSize) { | 489 if (shift < kSmiTagSize) { |
| 519 shl(reg, kSmiTagSize - shift); | 490 shl(reg, kSmiTagSize - shift); |
| 520 } else if (shift > kSmiTagSize) { | 491 } else if (shift > kSmiTagSize) { |
| 521 sar(reg, shift - kSmiTagSize); | 492 sar(reg, shift - kSmiTagSize); |
| 522 } | 493 } |
| 523 and_(reg, Immediate(mask)); | 494 and_(reg, Immediate(mask)); |
| 524 } | 495 } |
| 525 | 496 |
| 526 // Abort execution if argument is not a number, enabled via --debug-code. | |
| 527 void AssertNumber(Register object); | |
| 528 void AssertNotNumber(Register object); | |
| 529 | |
| 530 // Abort execution if argument is not a smi, enabled via --debug-code. | 497 // Abort execution if argument is not a smi, enabled via --debug-code. |
| 531 void AssertSmi(Register object); | 498 void AssertSmi(Register object); |
| 532 | 499 |
| 533 // Abort execution if argument is a smi, enabled via --debug-code. | 500 // Abort execution if argument is a smi, enabled via --debug-code. |
| 534 void AssertNotSmi(Register object); | 501 void AssertNotSmi(Register object); |
| 535 | 502 |
| 536 // Abort execution if argument is not a string, enabled via --debug-code. | |
| 537 void AssertString(Register object); | |
| 538 | |
| 539 // Abort execution if argument is not a name, enabled via --debug-code. | |
| 540 void AssertName(Register object); | |
| 541 | |
| 542 // Abort execution if argument is not a JSFunction, enabled via --debug-code. | 503 // Abort execution if argument is not a JSFunction, enabled via --debug-code. |
| 543 void AssertFunction(Register object); | 504 void AssertFunction(Register object); |
| 544 | 505 |
| 545 // Abort execution if argument is not a JSBoundFunction, | 506 // Abort execution if argument is not a JSBoundFunction, |
| 546 // enabled via --debug-code. | 507 // enabled via --debug-code. |
| 547 void AssertBoundFunction(Register object); | 508 void AssertBoundFunction(Register object); |
| 548 | 509 |
| 549 // Abort execution if argument is not a JSGeneratorObject, | 510 // Abort execution if argument is not a JSGeneratorObject, |
| 550 // enabled via --debug-code. | 511 // enabled via --debug-code. |
| 551 void AssertGeneratorObject(Register object); | 512 void AssertGeneratorObject(Register object); |
| 552 | 513 |
| 553 // Abort execution if argument is not a JSReceiver, enabled via --debug-code. | |
| 554 void AssertReceiver(Register object); | |
| 555 | |
| 556 // Abort execution if argument is not undefined or an AllocationSite, enabled | 514 // Abort execution if argument is not undefined or an AllocationSite, enabled |
| 557 // via --debug-code. | 515 // via --debug-code. |
| 558 void AssertUndefinedOrAllocationSite(Register object); | 516 void AssertUndefinedOrAllocationSite(Register object); |
| 559 | 517 |
| 560 // --------------------------------------------------------------------------- | 518 // --------------------------------------------------------------------------- |
| 561 // Exception handling | 519 // Exception handling |
| 562 | 520 |
| 563 // Push a new stack handler and link it into stack handler chain. | 521 // Push a new stack handler and link it into stack handler chain. |
| 564 void PushStackHandler(); | 522 void PushStackHandler(); |
| 565 | 523 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 // the end the loop, |current_address| takes the value of |end_address|. | 578 // the end the loop, |current_address| takes the value of |end_address|. |
| 621 void InitializeFieldsWithFiller(Register current_address, | 579 void InitializeFieldsWithFiller(Register current_address, |
| 622 Register end_address, Register filler); | 580 Register end_address, Register filler); |
| 623 | 581 |
| 624 // --------------------------------------------------------------------------- | 582 // --------------------------------------------------------------------------- |
| 625 // Support functions. | 583 // Support functions. |
| 626 | 584 |
| 627 // Check a boolean-bit of a Smi field. | 585 // Check a boolean-bit of a Smi field. |
| 628 void BooleanBitTest(Register object, int field_offset, int bit_index); | 586 void BooleanBitTest(Register object, int field_offset, int bit_index); |
| 629 | 587 |
| 630 // Check if result is zero and op is negative. | |
| 631 void NegativeZeroTest(Register result, Register op, Label* then_label); | |
| 632 | |
| 633 // Check if result is zero and any of op1 and op2 are negative. | |
| 634 // Register scratch is destroyed, and it must be different from op2. | |
| 635 void NegativeZeroTest(Register result, Register op1, Register op2, | |
| 636 Register scratch, Label* then_label); | |
| 637 | |
| 638 // --------------------------------------------------------------------------- | 588 // --------------------------------------------------------------------------- |
| 639 // Runtime calls | 589 // Runtime calls |
| 640 | 590 |
| 641 // Call a code stub. Generate the code if necessary. | 591 // Call a code stub. Generate the code if necessary. |
| 642 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); | 592 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); |
| 643 | 593 |
| 644 // Tail call a code stub (jump). Generate the code if necessary. | 594 // Tail call a code stub (jump). Generate the code if necessary. |
| 645 void TailCallStub(CodeStub* stub); | 595 void TailCallStub(CodeStub* stub); |
| 646 | 596 |
| 647 // Return from a code stub after popping its arguments. | |
| 648 void StubReturn(int argc); | |
| 649 | |
| 650 // Call a runtime routine. | 597 // Call a runtime routine. |
| 651 void CallRuntime(const Runtime::Function* f, int num_arguments, | 598 void CallRuntime(const Runtime::Function* f, int num_arguments, |
| 652 SaveFPRegsMode save_doubles = kDontSaveFPRegs); | 599 SaveFPRegsMode save_doubles = kDontSaveFPRegs); |
| 653 void CallRuntimeSaveDoubles(Runtime::FunctionId fid) { | 600 void CallRuntimeSaveDoubles(Runtime::FunctionId fid) { |
| 654 const Runtime::Function* function = Runtime::FunctionForId(fid); | 601 const Runtime::Function* function = Runtime::FunctionForId(fid); |
| 655 CallRuntime(function, function->nargs, kSaveFPRegs); | 602 CallRuntime(function, function->nargs, kSaveFPRegs); |
| 656 } | 603 } |
| 657 | 604 |
| 658 // Convenience function: Same as above, but takes the fid instead. | 605 // Convenience function: Same as above, but takes the fid instead. |
| 659 void CallRuntime(Runtime::FunctionId fid, | 606 void CallRuntime(Runtime::FunctionId fid, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 void IncrementCounter(Condition cc, StatsCounter* counter, int value); | 731 void IncrementCounter(Condition cc, StatsCounter* counter, int value); |
| 785 void DecrementCounter(Condition cc, StatsCounter* counter, int value); | 732 void DecrementCounter(Condition cc, StatsCounter* counter, int value); |
| 786 | 733 |
| 787 // --------------------------------------------------------------------------- | 734 // --------------------------------------------------------------------------- |
| 788 // Debugging | 735 // Debugging |
| 789 | 736 |
| 790 // Calls Abort(msg) if the condition cc is not satisfied. | 737 // Calls Abort(msg) if the condition cc is not satisfied. |
| 791 // Use --debug_code to enable. | 738 // Use --debug_code to enable. |
| 792 void Assert(Condition cc, BailoutReason reason); | 739 void Assert(Condition cc, BailoutReason reason); |
| 793 | 740 |
| 794 void AssertFastElements(Register elements); | |
| 795 | |
| 796 // Like Assert(), but always enabled. | 741 // Like Assert(), but always enabled. |
| 797 void Check(Condition cc, BailoutReason reason); | 742 void Check(Condition cc, BailoutReason reason); |
| 798 | 743 |
| 799 // Print a message to stdout and abort execution. | 744 // Print a message to stdout and abort execution. |
| 800 void Abort(BailoutReason reason); | 745 void Abort(BailoutReason reason); |
| 801 | 746 |
| 802 // Check that the stack is aligned. | 747 // Check that the stack is aligned. |
| 803 void CheckStackAlignment(); | 748 void CheckStackAlignment(); |
| 804 | 749 |
| 805 // Verify restrictions about code generated in stubs. | 750 // Verify restrictions about code generated in stubs. |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 inline Operand NativeContextOperand() { | 901 inline Operand NativeContextOperand() { |
| 957 return ContextOperand(esi, Context::NATIVE_CONTEXT_INDEX); | 902 return ContextOperand(esi, Context::NATIVE_CONTEXT_INDEX); |
| 958 } | 903 } |
| 959 | 904 |
| 960 #define ACCESS_MASM(masm) masm-> | 905 #define ACCESS_MASM(masm) masm-> |
| 961 | 906 |
| 962 } // namespace internal | 907 } // namespace internal |
| 963 } // namespace v8 | 908 } // namespace v8 |
| 964 | 909 |
| 965 #endif // V8_X87_MACRO_ASSEMBLER_X87_H_ | 910 #endif // V8_X87_MACRO_ASSEMBLER_X87_H_ |
| OLD | NEW |