Chromium Code Reviews| 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 |