OLD | NEW |
---|---|
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 } | 311 } |
312 | 312 |
313 Runtime::FunctionId function_id = | 313 Runtime::FunctionId function_id = |
314 static_cast<Runtime::FunctionId>(f->stub_id); | 314 static_cast<Runtime::FunctionId>(f->stub_id); |
315 RuntimeStub stub(function_id, num_arguments); | 315 RuntimeStub stub(function_id, num_arguments); |
316 CallStub(&stub); | 316 CallStub(&stub); |
317 } | 317 } |
318 | 318 |
319 | 319 |
320 void MacroAssembler::TailCallRuntime(ExternalReference const& ext, | 320 void MacroAssembler::TailCallRuntime(ExternalReference const& ext, |
321 int num_arguments) { | 321 int num_arguments, |
322 int result_size) { | |
322 // ----------- S t a t e ------------- | 323 // ----------- S t a t e ------------- |
323 // -- rsp[0] : return address | 324 // -- rsp[0] : return address |
324 // -- rsp[8] : argument num_arguments - 1 | 325 // -- rsp[8] : argument num_arguments - 1 |
325 // ... | 326 // ... |
326 // -- rsp[8 * num_arguments] : argument 0 (receiver) | 327 // -- rsp[8 * num_arguments] : argument 0 (receiver) |
327 // ----------------------------------- | 328 // ----------------------------------- |
328 | 329 |
329 // TODO(1236192): Most runtime routines don't need the number of | 330 // TODO(1236192): Most runtime routines don't need the number of |
330 // arguments passed in because it is constant. At some point we | 331 // arguments passed in because it is constant. At some point we |
331 // should remove this need and make the runtime routine entry code | 332 // should remove this need and make the runtime routine entry code |
332 // smarter. | 333 // smarter. |
333 movq(rax, Immediate(num_arguments)); | 334 movq(rax, Immediate(num_arguments)); |
334 JumpToBuiltin(ext); | 335 JumpToBuiltin(ext, result_size); |
335 } | 336 } |
336 | 337 |
337 | 338 |
338 void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) { | 339 void MacroAssembler::JumpToBuiltin(const ExternalReference& ext, |
340 int result_size) { | |
339 // Set the entry point and jump to the C entry runtime stub. | 341 // Set the entry point and jump to the C entry runtime stub. |
340 movq(rbx, ext); | 342 movq(rbx, ext); |
341 CEntryStub ces; | 343 CEntryStub ces(result_size); |
342 movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET); | 344 movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET); |
343 jmp(kScratchRegister); | 345 jmp(kScratchRegister); |
344 } | 346 } |
345 | 347 |
346 | 348 |
347 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { | 349 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { |
348 bool resolved; | 350 bool resolved; |
349 Handle<Code> code = ResolveBuiltin(id, &resolved); | 351 Handle<Code> code = ResolveBuiltin(id, &resolved); |
350 | 352 |
351 const char* name = Builtins::GetName(id); | 353 const char* name = Builtins::GetName(id); |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
964 movq(kScratchRegister, Immediate(Smi::FromInt(type))); | 966 movq(kScratchRegister, Immediate(Smi::FromInt(type))); |
965 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); | 967 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); |
966 Check(equal, "stack frame types must match"); | 968 Check(equal, "stack frame types must match"); |
967 } | 969 } |
968 movq(rsp, rbp); | 970 movq(rsp, rbp); |
969 pop(rbp); | 971 pop(rbp); |
970 } | 972 } |
971 | 973 |
972 | 974 |
973 | 975 |
974 void MacroAssembler::EnterExitFrame(StackFrame::Type type) { | 976 void MacroAssembler::EnterExitFrame(StackFrame::Type type, int result_size) { |
975 ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG); | 977 ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG); |
976 | 978 |
977 // Setup the frame structure on the stack. | 979 // Setup the frame structure on the stack. |
978 // All constants are relative to the frame pointer of the exit frame. | 980 // All constants are relative to the frame pointer of the exit frame. |
979 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); | 981 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); |
980 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); | 982 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); |
981 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); | 983 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); |
982 push(rbp); | 984 push(rbp); |
983 movq(rbp, rsp); | 985 movq(rbp, rsp); |
984 | 986 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1018 | 1020 |
1019 // Get the required frame alignment for the OS. | 1021 // Get the required frame alignment for the OS. |
1020 static const int kFrameAlignment = OS::ActivationFrameAlignment(); | 1022 static const int kFrameAlignment = OS::ActivationFrameAlignment(); |
1021 if (kFrameAlignment > 0) { | 1023 if (kFrameAlignment > 0) { |
1022 ASSERT(IsPowerOf2(kFrameAlignment)); | 1024 ASSERT(IsPowerOf2(kFrameAlignment)); |
1023 movq(kScratchRegister, Immediate(-kFrameAlignment)); | 1025 movq(kScratchRegister, Immediate(-kFrameAlignment)); |
1024 and_(rsp, kScratchRegister); | 1026 and_(rsp, kScratchRegister); |
1025 } | 1027 } |
1026 | 1028 |
1027 #ifdef _WIN64 | 1029 #ifdef _WIN64 |
1030 // Reserve space on stack for result and argument structures, if necessary. | |
1031 ASSERT(result_size <= 2); | |
1032 // The structure on the stack must be 16-byte aligned. | |
1033 int result_stack_space = (result_size < 2) ? 0 : result_size * kPointerSize; | |
1028 // Reserve space for the Arguments object. The Windows 64-bit ABI | 1034 // Reserve space for the Arguments object. The Windows 64-bit ABI |
1029 // requires us to pass this structure as a pointer to its location on | 1035 // requires us to pass this structure as a pointer to its location on |
1030 // the stack. The structure contains 2 pointers. | 1036 // the stack. The structure contains 2 values. |
1031 // The structure on the stack must be 16-byte aligned. | 1037 int argument_stack_space = 2 * kPointerSize; |
1032 // We also need backing space for 4 parameters, even though | 1038 // We also need backing space for 4 parameters, even though |
1033 // we only pass one parameter, and it is in a register. | 1039 // we only pass one or two parameter, and it is in a register. |
1034 subq(rsp, Immediate(6 * kPointerSize)); | 1040 int argument_mirror_space = 4 * kPointerSize; |
1041 int total_stack_space = | |
1042 argument_mirror_space + argument_stack_space + result_stack_space; | |
1043 subq(rsp, Immediate(total_stack_space)); | |
1035 ASSERT(kFrameAlignment == 2 * kPointerSize); // Change the padding if needed. | 1044 ASSERT(kFrameAlignment == 2 * kPointerSize); // Change the padding if needed. |
William Hesse
2009/09/07 14:34:18
This assert needs to be changed, to assert that th
Lasse Reichstein
2009/09/08 11:51:35
Rather, we should move the stack aligning code bel
William Hesse
2009/09/08 12:43:52
We don't know that we are subtracting a multiple o
| |
1036 #endif | 1045 #endif |
1037 | 1046 |
1038 // Patch the saved entry sp. | 1047 // Patch the saved entry sp. |
1039 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); | 1048 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); |
1040 } | 1049 } |
1041 | 1050 |
1042 | 1051 |
1043 void MacroAssembler::LeaveExitFrame(StackFrame::Type type) { | 1052 void MacroAssembler::LeaveExitFrame(StackFrame::Type type, int result_size) { |
1044 // Registers: | 1053 // Registers: |
1045 // r15 : argv | 1054 // r15 : argv |
1046 #ifdef ENABLE_DEBUGGER_SUPPORT | 1055 #ifdef ENABLE_DEBUGGER_SUPPORT |
1047 // Restore the memory copy of the registers by digging them out from | 1056 // Restore the memory copy of the registers by digging them out from |
1048 // the stack. This is needed to allow nested break points. | 1057 // the stack. This is needed to allow nested break points. |
1049 if (type == StackFrame::EXIT_DEBUG) { | 1058 if (type == StackFrame::EXIT_DEBUG) { |
1050 // It's okay to clobber register ebx below because we don't need | 1059 // It's okay to clobber register ebx below because we don't need |
1051 // the function pointer after this. | 1060 // the function pointer after this. |
1052 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; | 1061 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; |
1053 int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; | 1062 int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; |
1054 lea(rbx, Operand(rbp, kOffset)); | 1063 lea(rbx, Operand(rbp, kOffset)); |
1055 CopyRegistersFromStackToMemory(rbx, rcx, kJSCallerSaved); | 1064 CopyRegistersFromStackToMemory(rbx, rcx, kJSCallerSaved); |
1056 } | 1065 } |
1057 #endif | 1066 #endif |
1058 | 1067 |
1059 // Get the return address from the stack and restore the frame pointer. | 1068 // Get the return address from the stack and restore the frame pointer. |
1060 movq(rcx, Operand(rbp, 1 * kPointerSize)); | 1069 movq(rcx, Operand(rbp, 1 * kPointerSize)); |
1061 movq(rbp, Operand(rbp, 0 * kPointerSize)); | 1070 movq(rbp, Operand(rbp, 0 * kPointerSize)); |
1062 | 1071 |
1072 #ifdef _WIN64 | |
1073 // If return value is on the stack, pop it to registers. | |
1074 if (result_size > 1) { | |
1075 ASSERT_EQ(2, result_size); | |
1076 // Position above 4 argument mirrors and arguments object. | |
1077 movq(rax, Operand(rsp, 6 * kPointerSize)); | |
1078 movq(rdx, Operand(rsp, 7 * kPointerSize)); | |
1079 } | |
1080 #endif | |
1081 | |
1063 // Pop the arguments and the receiver from the caller stack. | 1082 // Pop the arguments and the receiver from the caller stack. |
1064 lea(rsp, Operand(r15, 1 * kPointerSize)); | 1083 lea(rsp, Operand(r15, 1 * kPointerSize)); |
1065 | 1084 |
1066 // Restore current context from top and clear it in debug mode. | 1085 // Restore current context from top and clear it in debug mode. |
1067 ExternalReference context_address(Top::k_context_address); | 1086 ExternalReference context_address(Top::k_context_address); |
1068 movq(kScratchRegister, context_address); | 1087 movq(kScratchRegister, context_address); |
1069 movq(rsi, Operand(kScratchRegister, 0)); | 1088 movq(rsi, Operand(kScratchRegister, 0)); |
1070 #ifdef DEBUG | 1089 #ifdef DEBUG |
1071 movq(Operand(kScratchRegister, 0), Immediate(0)); | 1090 movq(Operand(kScratchRegister, 0), Immediate(0)); |
1072 #endif | 1091 #endif |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1377 movq(kScratchRegister, new_space_allocation_top); | 1396 movq(kScratchRegister, new_space_allocation_top); |
1378 #ifdef DEBUG | 1397 #ifdef DEBUG |
1379 cmpq(object, Operand(kScratchRegister, 0)); | 1398 cmpq(object, Operand(kScratchRegister, 0)); |
1380 Check(below, "Undo allocation of non allocated memory"); | 1399 Check(below, "Undo allocation of non allocated memory"); |
1381 #endif | 1400 #endif |
1382 movq(Operand(kScratchRegister, 0), object); | 1401 movq(Operand(kScratchRegister, 0), object); |
1383 } | 1402 } |
1384 | 1403 |
1385 | 1404 |
1386 } } // namespace v8::internal | 1405 } } // namespace v8::internal |
OLD | NEW |