OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 | 518 |
519 __ bind(&patch); | 519 __ bind(&patch); |
520 GenerateTypeTransition(masm); | 520 GenerateTypeTransition(masm); |
521 } | 521 } |
522 | 522 |
523 | 523 |
524 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 524 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
525 __ PushCallerSaved(save_doubles_); | 525 __ PushCallerSaved(save_doubles_); |
526 const int argument_count = 1; | 526 const int argument_count = 1; |
527 __ PrepareCallCFunction(argument_count); | 527 __ PrepareCallCFunction(argument_count); |
528 #ifdef _WIN64 | 528 __ LoadAddress(arg_reg_1, |
529 __ LoadAddress(rcx, ExternalReference::isolate_address(masm->isolate())); | 529 ExternalReference::isolate_address(masm->isolate())); |
530 #else | |
531 __ LoadAddress(rdi, ExternalReference::isolate_address(masm->isolate())); | |
532 #endif | |
533 | 530 |
534 AllowExternalCallThatCantCauseGC scope(masm); | 531 AllowExternalCallThatCantCauseGC scope(masm); |
535 __ CallCFunction( | 532 __ CallCFunction( |
536 ExternalReference::store_buffer_overflow_function(masm->isolate()), | 533 ExternalReference::store_buffer_overflow_function(masm->isolate()), |
537 argument_count); | 534 argument_count); |
538 __ PopCallerSaved(save_doubles_); | 535 __ PopCallerSaved(save_doubles_); |
539 __ ret(0); | 536 __ ret(0); |
540 } | 537 } |
541 | 538 |
542 | 539 |
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1992 if (on_success != NULL) { | 1989 if (on_success != NULL) { |
1993 __ jmp(on_success); | 1990 __ jmp(on_success); |
1994 } | 1991 } |
1995 // Else: fall through. | 1992 // Else: fall through. |
1996 | 1993 |
1997 __ bind(&done); | 1994 __ bind(&done); |
1998 } | 1995 } |
1999 | 1996 |
2000 | 1997 |
2001 void MathPowStub::Generate(MacroAssembler* masm) { | 1998 void MathPowStub::Generate(MacroAssembler* masm) { |
2002 // Choose register conforming to calling convention (when bailing out). | |
2003 #ifdef _WIN64 | |
2004 const Register exponent = rdx; | 1999 const Register exponent = rdx; |
2005 #else | |
2006 const Register exponent = rdi; | |
2007 #endif | |
2008 const Register base = rax; | 2000 const Register base = rax; |
2009 const Register scratch = rcx; | 2001 const Register scratch = rcx; |
2010 const XMMRegister double_result = xmm3; | 2002 const XMMRegister double_result = xmm3; |
2011 const XMMRegister double_base = xmm2; | 2003 const XMMRegister double_base = xmm2; |
2012 const XMMRegister double_exponent = xmm1; | 2004 const XMMRegister double_exponent = xmm1; |
2013 const XMMRegister double_scratch = xmm4; | 2005 const XMMRegister double_scratch = xmm4; |
2014 | 2006 |
2015 Label call_runtime, done, exponent_not_smi, int_exponent; | 2007 Label call_runtime, done, exponent_not_smi, int_exponent; |
2016 | 2008 |
2017 // Save 1 in double_result - we need this several times later on. | 2009 // Save 1 in double_result - we need this several times later on. |
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3006 #endif | 2998 #endif |
3007 | 2999 |
3008 // Argument 5: static offsets vector buffer. | 3000 // Argument 5: static offsets vector buffer. |
3009 __ LoadAddress(r8, | 3001 __ LoadAddress(r8, |
3010 ExternalReference::address_of_static_offsets_vector(isolate)); | 3002 ExternalReference::address_of_static_offsets_vector(isolate)); |
3011 // Argument 5 passed in r8 on Linux and on the stack on Windows. | 3003 // Argument 5 passed in r8 on Linux and on the stack on Windows. |
3012 #ifdef _WIN64 | 3004 #ifdef _WIN64 |
3013 __ movq(Operand(rsp, (argument_slots_on_stack - 5) * kPointerSize), r8); | 3005 __ movq(Operand(rsp, (argument_slots_on_stack - 5) * kPointerSize), r8); |
3014 #endif | 3006 #endif |
3015 | 3007 |
3016 // First four arguments are passed in registers on both Linux and Windows. | |
3017 #ifdef _WIN64 | |
3018 Register arg4 = r9; | |
3019 Register arg3 = r8; | |
3020 Register arg2 = rdx; | |
3021 Register arg1 = rcx; | |
3022 #else | |
3023 Register arg4 = rcx; | |
3024 Register arg3 = rdx; | |
3025 Register arg2 = rsi; | |
3026 Register arg1 = rdi; | |
3027 #endif | |
3028 | |
3029 // Keep track on aliasing between argX defined above and the registers used. | 3008 // Keep track on aliasing between argX defined above and the registers used. |
3030 // rdi: subject string | 3009 // rdi: subject string |
3031 // rbx: previous index | 3010 // rbx: previous index |
mvstanton
2013/04/24 10:54:54
These comments should be updated to refer to arg_r
| |
3032 // rcx: encoding of subject string (1 if ASCII 0 if two_byte); | 3011 // rcx: encoding of subject string (1 if ASCII 0 if two_byte); |
3033 // r11: code | 3012 // r11: code |
3034 // r14: slice offset | 3013 // r14: slice offset |
3035 // r15: original subject string | 3014 // r15: original subject string |
3036 | 3015 |
3037 // Argument 2: Previous index. | 3016 // Argument 2: Previous index. |
3038 __ movq(arg2, rbx); | 3017 __ movq(arg_reg_2, rbx); |
3039 | 3018 |
3040 // Argument 4: End of string data | 3019 // Argument 4: End of string data |
3041 // Argument 3: Start of string data | 3020 // Argument 3: Start of string data |
3042 Label setup_two_byte, setup_rest, got_length, length_not_from_slice; | 3021 Label setup_two_byte, setup_rest, got_length, length_not_from_slice; |
3043 // Prepare start and end index of the input. | 3022 // Prepare start and end index of the input. |
3044 // Load the length from the original sliced string if that is the case. | 3023 // Load the length from the original sliced string if that is the case. |
3045 __ addq(rbx, r14); | 3024 __ addq(rbx, r14); |
3046 __ SmiToInteger32(arg3, FieldOperand(r15, String::kLengthOffset)); | 3025 __ SmiToInteger32(arg_reg_3, FieldOperand(r15, String::kLengthOffset)); |
3047 __ addq(r14, arg3); // Using arg3 as scratch. | 3026 __ addq(r14, arg_reg_3); // Using arg3 as scratch. |
3048 | 3027 |
3049 // rbx: start index of the input | 3028 // rbx: start index of the input |
3050 // r14: end index of the input | 3029 // r14: end index of the input |
3051 // r15: original subject string | 3030 // r15: original subject string |
3052 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string. | 3031 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string. |
3053 __ j(zero, &setup_two_byte, Label::kNear); | 3032 __ j(zero, &setup_two_byte, Label::kNear); |
3054 __ lea(arg4, FieldOperand(rdi, r14, times_1, SeqOneByteString::kHeaderSize)); | 3033 __ lea(arg_reg_4, |
3055 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqOneByteString::kHeaderSize)); | 3034 FieldOperand(rdi, r14, times_1, SeqOneByteString::kHeaderSize)); |
3035 __ lea(arg_reg_3, | |
3036 FieldOperand(rdi, rbx, times_1, SeqOneByteString::kHeaderSize)); | |
3056 __ jmp(&setup_rest, Label::kNear); | 3037 __ jmp(&setup_rest, Label::kNear); |
3057 __ bind(&setup_two_byte); | 3038 __ bind(&setup_two_byte); |
3058 __ lea(arg4, FieldOperand(rdi, r14, times_2, SeqTwoByteString::kHeaderSize)); | 3039 __ lea(arg_reg_4, |
3059 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize)); | 3040 FieldOperand(rdi, r14, times_2, SeqTwoByteString::kHeaderSize)); |
3041 __ lea(arg_reg_3, | |
3042 FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize)); | |
3060 __ bind(&setup_rest); | 3043 __ bind(&setup_rest); |
3061 | 3044 |
3062 // Argument 1: Original subject string. | 3045 // Argument 1: Original subject string. |
3063 // The original subject is in the previous stack frame. Therefore we have to | 3046 // The original subject is in the previous stack frame. Therefore we have to |
3064 // use rbp, which points exactly to one pointer size below the previous rsp. | 3047 // use rbp, which points exactly to one pointer size below the previous rsp. |
3065 // (Because creating a new stack frame pushes the previous rbp onto the stack | 3048 // (Because creating a new stack frame pushes the previous rbp onto the stack |
3066 // and thereby moves up rsp by one kPointerSize.) | 3049 // and thereby moves up rsp by one kPointerSize.) |
3067 __ movq(arg1, r15); | 3050 __ movq(arg_reg_1, r15); |
3068 | 3051 |
3069 // Locate the code entry and call it. | 3052 // Locate the code entry and call it. |
3070 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 3053 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
3071 __ call(r11); | 3054 __ call(r11); |
3072 | 3055 |
3073 __ LeaveApiExitFrame(); | 3056 __ LeaveApiExitFrame(); |
3074 | 3057 |
3075 // Check the result. | 3058 // Check the result. |
3076 Label success; | 3059 Label success; |
3077 Label exception; | 3060 Label exception; |
(...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4082 // Check stack alignment. | 4065 // Check stack alignment. |
4083 if (FLAG_debug_code) { | 4066 if (FLAG_debug_code) { |
4084 __ CheckStackAlignment(); | 4067 __ CheckStackAlignment(); |
4085 } | 4068 } |
4086 | 4069 |
4087 if (do_gc) { | 4070 if (do_gc) { |
4088 // Pass failure code returned from last attempt as first argument to | 4071 // Pass failure code returned from last attempt as first argument to |
4089 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the | 4072 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the |
4090 // stack is known to be aligned. This function takes one argument which is | 4073 // stack is known to be aligned. This function takes one argument which is |
4091 // passed in register. | 4074 // passed in register. |
4092 #ifdef _WIN64 | 4075 __ movq(arg_reg_1, rax); |
4093 __ movq(rcx, rax); | |
4094 #else // _WIN64 | |
4095 __ movq(rdi, rax); | |
4096 #endif | |
4097 __ movq(kScratchRegister, | 4076 __ movq(kScratchRegister, |
4098 ExternalReference::perform_gc_function(masm->isolate())); | 4077 ExternalReference::perform_gc_function(masm->isolate())); |
4099 __ call(kScratchRegister); | 4078 __ call(kScratchRegister); |
4100 } | 4079 } |
4101 | 4080 |
4102 ExternalReference scope_depth = | 4081 ExternalReference scope_depth = |
4103 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); | 4082 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); |
4104 if (always_allocate_scope) { | 4083 if (always_allocate_scope) { |
4105 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); | 4084 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); |
4106 __ incl(scope_depth_operand); | 4085 __ incl(scope_depth_operand); |
(...skipping 2367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6474 CheckNeedsToInformIncrementalMarker( | 6453 CheckNeedsToInformIncrementalMarker( |
6475 masm, kReturnOnNoNeedToInformIncrementalMarker, mode); | 6454 masm, kReturnOnNoNeedToInformIncrementalMarker, mode); |
6476 InformIncrementalMarker(masm, mode); | 6455 InformIncrementalMarker(masm, mode); |
6477 regs_.Restore(masm); | 6456 regs_.Restore(masm); |
6478 __ ret(0); | 6457 __ ret(0); |
6479 } | 6458 } |
6480 | 6459 |
6481 | 6460 |
6482 void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm, Mode mode) { | 6461 void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm, Mode mode) { |
6483 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_); | 6462 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_); |
6484 #ifdef _WIN64 | |
6485 Register arg3 = r8; | |
6486 Register arg2 = rdx; | |
6487 Register arg1 = rcx; | |
6488 #else | |
6489 Register arg3 = rdx; | |
6490 Register arg2 = rsi; | |
6491 Register arg1 = rdi; | |
6492 #endif | |
6493 Register address = | 6463 Register address = |
6494 arg1.is(regs_.address()) ? kScratchRegister : regs_.address(); | 6464 arg_reg_1.is(regs_.address()) ? kScratchRegister : regs_.address(); |
6495 ASSERT(!address.is(regs_.object())); | 6465 ASSERT(!address.is(regs_.object())); |
6496 ASSERT(!address.is(arg1)); | 6466 ASSERT(!address.is(arg_reg_1)); |
6497 __ Move(address, regs_.address()); | 6467 __ Move(address, regs_.address()); |
6498 __ Move(arg1, regs_.object()); | 6468 __ Move(arg_reg_1, regs_.object()); |
6499 // TODO(gc) Can we just set address arg2 in the beginning? | 6469 // TODO(gc) Can we just set address arg2 in the beginning? |
6500 __ Move(arg2, address); | 6470 __ Move(arg_reg_2, address); |
6501 __ LoadAddress(arg3, ExternalReference::isolate_address(masm->isolate())); | 6471 __ LoadAddress(arg_reg_3, |
6472 ExternalReference::isolate_address(masm->isolate())); | |
6502 int argument_count = 3; | 6473 int argument_count = 3; |
6503 | 6474 |
6504 AllowExternalCallThatCantCauseGC scope(masm); | 6475 AllowExternalCallThatCantCauseGC scope(masm); |
6505 __ PrepareCallCFunction(argument_count); | 6476 __ PrepareCallCFunction(argument_count); |
6506 if (mode == INCREMENTAL_COMPACTION) { | 6477 if (mode == INCREMENTAL_COMPACTION) { |
6507 __ CallCFunction( | 6478 __ CallCFunction( |
6508 ExternalReference::incremental_evacuation_record_write_function( | 6479 ExternalReference::incremental_evacuation_record_write_function( |
6509 masm->isolate()), | 6480 masm->isolate()), |
6510 argument_count); | 6481 argument_count); |
6511 } else { | 6482 } else { |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6767 #endif | 6738 #endif |
6768 | 6739 |
6769 __ Ret(); | 6740 __ Ret(); |
6770 } | 6741 } |
6771 | 6742 |
6772 #undef __ | 6743 #undef __ |
6773 | 6744 |
6774 } } // namespace v8::internal | 6745 } } // namespace v8::internal |
6775 | 6746 |
6776 #endif // V8_TARGET_ARCH_X64 | 6747 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |