1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_RUNTIME_RUNTIME_UTILS_H_
6 #define V8_RUNTIME_RUNTIME_UTILS_H_
7 
8 #include "src/base/logging.h"
9 #include "src/common/globals.h"
10 #include "src/objects/objects.h"
11 #include "src/runtime/runtime.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // A mechanism to return a pair of Object pointers in registers (if possible).
17 // How this is achieved is calling convention-dependent.
18 // All currently supported x86 compiles uses calling conventions that are cdecl
19 // variants where a 64-bit value is returned in two 32-bit registers
20 // (edx:eax on ia32, r1:r0 on ARM).
21 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
22 // In Win64 calling convention, a struct of two pointers is returned in memory,
23 // allocated by the caller, and passed as a pointer in a hidden first parameter.
24 #ifdef V8_HOST_ARCH_64_BIT
25 struct ObjectPair {
26   Address x;
27   Address y;
28 };
29 
MakePair(Object x, Object y)30 static inline ObjectPair MakePair(Object x, Object y) {
31   ObjectPair result = {x.ptr(), y.ptr()};
32   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
33   // In Win64 they are assigned to a hidden first argument.
34   return result;
35 }
36 #else
37 using ObjectPair = uint64_t;
38 static inline ObjectPair MakePair(Object x, Object y) {
39 #if defined(V8_TARGET_LITTLE_ENDIAN)
40   return x.ptr() | (static_cast<ObjectPair>(y.ptr()) << 32);
41 #elif defined(V8_TARGET_BIG_ENDIAN)
42   return y->ptr() | (static_cast<ObjectPair>(x->ptr()) << 32);
43 #else
44 #error Unknown endianness
45 #endif
46 }
47 #endif
48 
49 }  // namespace internal
50 }  // namespace v8
51 
52 #endif  // V8_RUNTIME_RUNTIME_UTILS_H_
53