Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 201042: Win64 - Allow returning two values from a runtime function. (Closed)
Patch Set: Fixed typo. Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698