Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (279027 => 279028)
--- trunk/Source/_javascript_Core/ChangeLog 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,3 +1,16 @@
+2021-06-17 Mark Lam <mark....@apple.com>
+
+ Define MacroAssemblerARM64E::numberOfPACBits based on OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH).
+ https://bugs.webkit.org/show_bug.cgi?id=227147
+ rdar://78785309
+
+ Reviewed by Saam Barati.
+
+ * assembler/MacroAssemblerARM64E.h:
+ * bytecode/CodeOrigin.h:
+ * runtime/JSString.h:
+ * runtime/OptionsList.h:
+
2021-06-17 Fujii Hironori <hironori.fu...@sony.com>
Reimplement JSC::CachePayload without FileSystem::unmapViewOfFile and FileSystem::MappedFileData::leakHandle
Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64E.h (279027 => 279028)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64E.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64E.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
#if ENABLE(ASSEMBLER) && CPU(ARM64E)
#include "DisallowMacroScratchRegisterUsage.h"
+#include <wtf/MathExtras.h>
// We need to include this before MacroAssemblerARM64.h because MacroAssemblerARM64
// will be defined in terms of ARM64EAssembler for ARM64E.
@@ -38,6 +39,10 @@
#include <WebKitAdditions/JITCageAdditions.h>
#endif
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace JSC {
using Assembler = TARGET_ASSEMBLER;
@@ -44,8 +49,9 @@
class MacroAssemblerARM64E : public MacroAssemblerARM64 {
public:
- static constexpr unsigned numberOfPACBits = 25;
- static constexpr uintptr_t nonPACBitsMask = (1ull << (64 - numberOfPACBits)) - 1;
+ static constexpr unsigned numberOfPointerBits = sizeof(void*) * CHAR_BIT;
+ static constexpr unsigned numberOfPACBits = numberOfPointerBits - OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH);
+ static constexpr uintptr_t nonPACBitsMask = (1ull << (numberOfPointerBits - numberOfPACBits)) - 1;
ALWAYS_INLINE void tagReturnAddress()
{
Modified: trunk/Source/_javascript_Core/bytecode/CodeOrigin.h (279027 => 279028)
--- trunk/Source/_javascript_Core/bytecode/CodeOrigin.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/_javascript_Core/bytecode/CodeOrigin.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -29,10 +29,15 @@
#include <limits.h>
#include <wtf/HashMap.h>
+#include <wtf/MathExtras.h>
#include <wtf/PrintStream.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace JSC {
class CodeBlock;
Modified: trunk/Source/_javascript_Core/runtime/JSString.h (279027 => 279028)
--- trunk/Source/_javascript_Core/runtime/JSString.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/_javascript_Core/runtime/JSString.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -34,8 +34,13 @@
#include <array>
#include <wtf/CheckedArithmetic.h>
#include <wtf/ForbidHeapAllocation.h>
+#include <wtf/MathExtras.h>
#include <wtf/text/StringView.h>
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace JSC {
class JSString;
Modified: trunk/Source/_javascript_Core/runtime/OptionsList.h (279027 => 279028)
--- trunk/Source/_javascript_Core/runtime/OptionsList.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/_javascript_Core/runtime/OptionsList.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -26,7 +26,12 @@
#pragma once
#include "GCLogging.h"
+#include <wtf/MathExtras.h>
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
using WTF::PrintStream;
namespace JSC {
Modified: trunk/Source/WTF/ChangeLog (279027 => 279028)
--- trunk/Source/WTF/ChangeLog 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/WTF/ChangeLog 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,3 +1,28 @@
+2021-06-17 Mark Lam <mark....@apple.com>
+
+ Define MacroAssemblerARM64E::numberOfPACBits based on OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH).
+ https://bugs.webkit.org/show_bug.cgi?id=227147
+ rdar://78785309
+
+ Reviewed by Saam Barati.
+
+ For OS(DARWIN), define OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH) in terms of
+ MACH_VM_MAX_ADDRESS, which is provided by the SDK. This ensures that it is
+ correct for each target OS(DARWIN) platform.
+
+ Also update an assertion in WTFAssertions.cpp to verify that address bits are
+ less than 48. The purpose of this assertion is to ensure that our 64-bit NaN
+ boxing encoding for JSValues will work. Hence, we should use the encoding limit
+ for pointers of 48 bits. It no longer makes sense to assert based on
+ OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH), because OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH)
+ is defined in terms of MACH_VM_MAX_ADDRESS.
+
+ * wtf/CagedPtr.h:
+ * wtf/CompactPointerTuple.h:
+ * wtf/PlatformOS.h:
+ * wtf/WTFAssertions.cpp:
+ * wtf/threads/Signals.cpp:
+
2021-06-17 Fujii Hironori <hironori.fu...@sony.com>
[Win] WTF.ParseInteger and WTF.ParseIntegerAllowingTrailingJunk are failing
Modified: trunk/Source/WTF/wtf/CagedPtr.h (279027 => 279028)
--- trunk/Source/WTF/wtf/CagedPtr.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/WTF/wtf/CagedPtr.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,11 +26,16 @@
#pragma once
#include <wtf/Gigacage.h>
+#include <wtf/MathExtras.h>
#include <wtf/PtrTag.h>
#include <wtf/RawPtrTraits.h>
#include <climits>
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace WTF {
constexpr bool tagCagedPtr = true;
@@ -39,8 +44,9 @@
class CagedPtr {
public:
static constexpr Gigacage::Kind kind = passedKind;
- static constexpr unsigned numberOfPACBits = 25;
- static constexpr uintptr_t nonPACBitsMask = (1ull << ((sizeof(T*) * CHAR_BIT) - numberOfPACBits)) - 1;
+ static constexpr unsigned numberOfPointerBits = sizeof(T*) * CHAR_BIT;
+ static constexpr unsigned numberOfPACBits = numberOfPointerBits - OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH);
+ static constexpr uintptr_t nonPACBitsMask = (1ull << (numberOfPointerBits - numberOfPACBits)) - 1;
CagedPtr() : CagedPtr(nullptr) { }
CagedPtr(std::nullptr_t)
Modified: trunk/Source/WTF/wtf/CompactPointerTuple.h (279027 => 279028)
--- trunk/Source/WTF/wtf/CompactPointerTuple.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/WTF/wtf/CompactPointerTuple.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -28,8 +28,13 @@
#include <type_traits>
#include <wtf/FastMalloc.h>
+#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace WTF {
// The goal of this class is folding a pointer and 2 bytes value into 8 bytes in both 32bit and 64bit architectures.
Modified: trunk/Source/WTF/wtf/Packed.h (279027 => 279028)
--- trunk/Source/WTF/wtf/Packed.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/WTF/wtf/Packed.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -33,6 +33,10 @@
#include <wtf/StdLibExtras.h>
#include <wtf/UnalignedAccess.h>
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace WTF {
template<typename T>
Modified: trunk/Source/WTF/wtf/PlatformOS.h (279027 => 279028)
--- trunk/Source/WTF/wtf/PlatformOS.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/WTF/wtf/PlatformOS.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2021 Apple Inc. All rights reserved.
* Copyright (C) 2007-2009 Torch Mobile, Inc.
* Copyright (C) 2010, 2011 Research In Motion Limited. All rights reserved.
*
@@ -38,7 +38,6 @@
#include <TargetConditionals.h>
#endif
-
/* OS() - underlying operating system; only to be used for mandated low-level services like
virtual memory, not to choose a GUI toolkit */
#define OS(WTF_FEATURE) (defined WTF_OS_##WTF_FEATURE && WTF_OS_##WTF_FEATURE)
@@ -137,8 +136,8 @@
#if CPU(ADDRESS64)
-#if (OS(IOS) || OS(TVOS) || OS(WATCHOS)) && CPU(ARM64)
-#define WTF_OS_CONSTANT_EFFECTIVE_ADDRESS_WIDTH 36
+#if OS(DARWIN)
+#define WTF_OS_CONSTANT_EFFECTIVE_ADDRESS_WIDTH (WTF::getMSBSetConstexpr(MACH_VM_MAX_ADDRESS) + 1)
#else
/* We strongly assume that effective address width is <= 48 in 64bit architectures (e.g. NaN boxing). */
#define WTF_OS_CONSTANT_EFFECTIVE_ADDRESS_WIDTH 48
Modified: trunk/Source/WTF/wtf/WTFAssertions.cpp (279027 => 279028)
--- trunk/Source/WTF/wtf/WTFAssertions.cpp 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/WTF/wtf/WTFAssertions.cpp 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,7 +50,8 @@
static_assert(sizeof(RefCountedArray<DummyStruct>) == sizeof(void*), "");
#if OS(DARWIN) && CPU(ADDRESS64)
-static_assert(MACH_VM_MAX_ADDRESS <= ((1ULL << OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH)) - 1));
+// NaN boxing encoding relies on this.
+static_assert(MACH_VM_MAX_ADDRESS <= (1ull << 48));
#endif
} // namespace WTF
Modified: trunk/Source/WTF/wtf/threads/Signals.cpp (279027 => 279028)
--- trunk/Source/WTF/wtf/threads/Signals.cpp 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/WTF/wtf/threads/Signals.cpp 2021-06-18 01:44:42 UTC (rev 279028)
@@ -44,8 +44,13 @@
#include <mach/thread_act.h>
#endif
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
#include <wtf/Atomics.h>
#include <wtf/DataLog.h>
+#include <wtf/MathExtras.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/PlatformRegisters.h>
#include <wtf/ThreadGroup.h>
Modified: trunk/Source/bmalloc/ChangeLog (279027 => 279028)
--- trunk/Source/bmalloc/ChangeLog 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/bmalloc/ChangeLog 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,3 +1,23 @@
+2021-06-17 Mark Lam <mark....@apple.com>
+
+ Define MacroAssemblerARM64E::numberOfPACBits based on OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH).
+ https://bugs.webkit.org/show_bug.cgi?id=227147
+ rdar://78785309
+
+ Reviewed by Saam Barati.
+
+ For OS(DARWIN), define BOS_EFFECTIVE_ADDRESS_WIDTH in terms of MACH_VM_MAX_ADDRESS,
+ which is provided by the SDK. This ensures that it is correct for each target
+ OS(DARWIN) platform.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::clzConstexpr):
+ (bmalloc::getMSBSetConstexpr):
+ * bmalloc/BPlatform.h:
+ * bmalloc/Gigacage.h:
+ * bmalloc/ObjectTypeTable.h:
+ * bmalloc/Packed.h:
+
2021-06-03 Michael Saboff <msab...@apple.com>
Unreviewed, rolling out r278278.
Modified: trunk/Source/bmalloc/bmalloc/Algorithm.h (279027 => 279028)
--- trunk/Source/bmalloc/bmalloc/Algorithm.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/bmalloc/bmalloc/Algorithm.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -169,6 +169,23 @@
}
#endif
+template <typename T>
+constexpr unsigned clzConstexpr(T value)
+{
+ constexpr unsigned bitSize = sizeof(T) * CHAR_BIT;
+
+ using UT = typename std::make_unsigned<T>::type;
+ UT uValue = value;
+
+ unsigned zeroCount = 0;
+ for (int i = bitSize - 1; i >= 0; i--) {
+ if (uValue >> i)
+ break;
+ zeroCount++;
+ }
+ return zeroCount;
+}
+
constexpr unsigned long log2(unsigned long value)
{
return bitCount<unsigned long>() - 1 - __builtin_clzl(value);
@@ -262,6 +279,13 @@
return ctzConstexpr(t);
}
+template<typename T>
+constexpr unsigned getMSBSetConstexpr(T t)
+{
+ constexpr unsigned bitSize = sizeof(T) * CHAR_BIT;
+ return bitSize - 1 - clzConstexpr(t);
+}
+
// From http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
constexpr uint32_t roundUpToPowerOfTwo(uint32_t v)
{
Modified: trunk/Source/bmalloc/bmalloc/BPlatform.h (279027 => 279028)
--- trunk/Source/bmalloc/bmalloc/BPlatform.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/bmalloc/bmalloc/BPlatform.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -274,8 +274,8 @@
#endif
#if BCPU(ADDRESS64)
-#if (BOS(IOS) || BOS(TVOS) || BOS(WATCHOS)) && BCPU(ARM64)
-#define BOS_EFFECTIVE_ADDRESS_WIDTH 36
+#if BOS(DARWIN)
+#define BOS_EFFECTIVE_ADDRESS_WIDTH (bmalloc::getMSBSetConstexpr(MACH_VM_MAX_ADDRESS) + 1)
#else
/* We strongly assume that effective address width is <= 48 in 64bit architectures (e.g. NaN boxing). */
#define BOS_EFFECTIVE_ADDRESS_WIDTH 48
Modified: trunk/Source/bmalloc/bmalloc/Gigacage.h (279027 => 279028)
--- trunk/Source/bmalloc/bmalloc/Gigacage.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@
#pragma once
+#include "Algorithm.h"
#include "BAssert.h"
#include "BExport.h"
#include "BInline.h"
@@ -35,6 +36,10 @@
#include <cstddef>
#include <inttypes.h>
+#if BOS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
#if ((BOS(DARWIN) || BOS(LINUX)) && \
(BCPU(X86_64) || (BCPU(ARM64) && !defined(__ILP32__) && (!BPLATFORM(IOS_FAMILY) || BPLATFORM(IOS)))))
#define GIGACAGE_ENABLED 1
@@ -61,16 +66,12 @@
#if GIGACAGE_ENABLED
-#if BOS_EFFECTIVE_ADDRESS_WIDTH < 48
-constexpr size_t primitiveGigacageSize = 2 * bmalloc::Sizes::GB;
-constexpr size_t jsValueGigacageSize = 2 * bmalloc::Sizes::GB;
-constexpr size_t maximumCageSizeReductionForSlide = bmalloc::Sizes::GB / 4;
-#else
-constexpr size_t primitiveGigacageSize = 32 * bmalloc::Sizes::GB;
-constexpr size_t jsValueGigacageSize = 16 * bmalloc::Sizes::GB;
-constexpr size_t maximumCageSizeReductionForSlide = 4 * bmalloc::Sizes::GB;
-#endif
+constexpr bool useLargeGigacage = BOS_EFFECTIVE_ADDRESS_WIDTH > 36;
+constexpr size_t primitiveGigacageSize = (useLargeGigacage ? 32 : 2) * bmalloc::Sizes::GB;
+constexpr size_t jsValueGigacageSize = (useLargeGigacage ? 16 : 2) * bmalloc::Sizes::GB;
+constexpr size_t maximumCageSizeReductionForSlide = useLargeGigacage ? 4 * bmalloc::Sizes::GB : bmalloc::Sizes::GB / 4;
+
// In Linux, if `vm.overcommit_memory = 2` is specified, mmap with large size can fail if it exceeds the size of RAM.
// So we specify GIGACAGE_ALLOCATION_CAN_FAIL = 1.
#if BOS(LINUX)
Modified: trunk/Source/bmalloc/bmalloc/ObjectTypeTable.h (279027 => 279028)
--- trunk/Source/bmalloc/bmalloc/ObjectTypeTable.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/bmalloc/bmalloc/ObjectTypeTable.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,10 +25,15 @@
#pragma once
+#include "Algorithm.h"
#include "Mutex.h"
#include "ObjectType.h"
#include "Sizes.h"
+#if BOS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace bmalloc {
class Chunk;
Modified: trunk/Source/bmalloc/bmalloc/Packed.h (279027 => 279028)
--- trunk/Source/bmalloc/bmalloc/Packed.h 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Source/bmalloc/bmalloc/Packed.h 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2019-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,6 +29,10 @@
#include "StdLibExtras.h"
#include <array>
+#if BOS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace bmalloc {
template<typename T>
Modified: trunk/Tools/ChangeLog (279027 => 279028)
--- trunk/Tools/ChangeLog 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Tools/ChangeLog 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,3 +1,13 @@
+2021-06-17 Mark Lam <mark....@apple.com>
+
+ Define MacroAssemblerARM64E::numberOfPACBits based on OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH).
+ https://bugs.webkit.org/show_bug.cgi?id=227147
+ rdar://78785309
+
+ Reviewed by Saam Barati.
+
+ * TestWebKitAPI/Tests/WTF/Packed.cpp:
+
2021-06-17 Fujii Hironori <hironori.fu...@sony.com>
[Win] WTF.ParseInteger and WTF.ParseIntegerAllowingTrailingJunk are failing
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp (279027 => 279028)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp 2021-06-18 01:27:53 UTC (rev 279027)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp 2021-06-18 01:44:42 UTC (rev 279028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2019-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,8 +27,13 @@
#include <wtf/Packed.h>
#include <wtf/HashMap.h>
+#include <wtf/MathExtras.h>
#include <wtf/Vector.h>
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
namespace TestWebKitAPI {
struct PackedPair {