Skip to content
Permalink
Browse files
BigInt should store its data in the primitive gigacage.
https://bugs.webkit.org/show_bug.cgi?id=194888

Reviewed by Mark Lam.

We should put these bits in the primitive gigacage to reduce the
value of type confusing a BigInt as a different cell and using the
digits as a way to create an arbitrary pointer. I didn't worry
about length/sign as they are not possible to forge a pointer with.

We also put JSBigInt in IsoSubspace.

* runtime/CellSize.h:
(JSC::isDynamicallySizedType):
(JSC::cellSize):
* runtime/JSBigInt.cpp:
(JSC::JSBigInt::JSBigInt):
(JSC::JSBigInt::destroy):
(JSC::JSBigInt::createWithLengthUnchecked):
* runtime/JSBigInt.h:
(JSC::JSBigInt::allocationSize): Deleted.
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

Canonical link: https://commits.webkit.org/217573@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252538 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Constellation committed Nov 18, 2019
1 parent 6fdaa4e commit 3e0ce76ee7e11462ac71d464a1f4499ba0221e5c
Showing 6 changed files with 54 additions and 26 deletions.
@@ -1,3 +1,30 @@
2019-11-18 Keith Miller <keith_miller@apple.com> and Yusuke Suzuki <ysuzuki@apple.com>

BigInt should store its data in the primitive gigacage.
https://bugs.webkit.org/show_bug.cgi?id=194888

Reviewed by Mark Lam.

We should put these bits in the primitive gigacage to reduce the
value of type confusing a BigInt as a different cell and using the
digits as a way to create an arbitrary pointer. I didn't worry
about length/sign as they are not possible to forge a pointer with.

We also put JSBigInt in IsoSubspace.

* runtime/CellSize.h:
(JSC::isDynamicallySizedType):
(JSC::cellSize):
* runtime/JSBigInt.cpp:
(JSC::JSBigInt::JSBigInt):
(JSC::JSBigInt::destroy):
(JSC::JSBigInt::createWithLengthUnchecked):
* runtime/JSBigInt.h:
(JSC::JSBigInt::allocationSize): Deleted.
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

2019-11-15 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] Remove index-masking on ScopedArguments and put it in IsoSubspace
@@ -35,8 +35,7 @@ namespace JSC {

inline constexpr bool isDynamicallySizedType(JSType type)
{
if (type == BigIntType
|| type == DirectArgumentsType
if (type == DirectArgumentsType
|| type == FinalObjectType
|| type == LexicalEnvironmentType
|| type == ModuleEnvironmentType
@@ -53,10 +52,6 @@ inline size_t cellSize(VM& vm, JSCell* cell)

if (isDynamicallySizedType(cellType)) {
switch (cellType) {
case BigIntType: {
auto* bigInt = jsCast<JSBigInt*>(cell);
return JSBigInt::allocationSize(bigInt->length());
}
case DirectArgumentsType: {
auto* args = jsCast<DirectArguments*>(cell);
return DirectArguments::allocationSize(args->m_minCapacity);
@@ -61,11 +61,17 @@ namespace JSC {

const ClassInfo JSBigInt::s_info = { "BigInt", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSBigInt) };

JSBigInt::JSBigInt(VM& vm, Structure* structure, unsigned length)
JSBigInt::JSBigInt(VM& vm, Structure* structure, Digit* data, unsigned length)
: Base(vm, structure)
, m_length(length)
, m_data(data, length)
{ }

void JSBigInt::destroy(JSCell* thisCell)
{
static_cast<JSBigInt*>(thisCell)->~JSBigInt();
}

void JSBigInt::initialize(InitializationType initType)
{
if (initType == InitializationType::WithZero)
@@ -101,7 +107,8 @@ JSBigInt* JSBigInt::tryCreateWithLength(JSGlobalObject* globalObject, unsigned l
JSBigInt* JSBigInt::createWithLengthUnchecked(VM& vm, unsigned length)
{
ASSERT(length <= maxLength);
JSBigInt* bigInt = new (NotNull, allocateCell<JSBigInt>(vm.heap, allocationSize(length))) JSBigInt(vm, vm.bigIntStructure.get(), length);
void* data = Gigacage::malloc(Gigacage::Primitive, length * sizeof(Digit));
JSBigInt* bigInt = new (NotNull, allocateCell<JSBigInt>(vm.heap)) JSBigInt(vm, vm.bigIntStructure.get(), reinterpret_cast<Digit*>(data), length);
bigInt->finishCreation(vm);
return bigInt;
}
@@ -29,21 +29,29 @@
#include "CPU.h"
#include "ExceptionHelpers.h"
#include "JSObject.h"
#include <wtf/CagedPtr.h>
#include <wtf/CagedUniquePtr.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringView.h>
#include <wtf/text/WTFString.h>

namespace JSC {

class JSBigInt final : public JSCell {
public:
using Base = JSCell;
using Digit = UCPURegister;

static constexpr unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal | OverridesToThis;
friend class CachedBigInt;

public:
static constexpr bool needsDestruction = true;
static void destroy(JSCell*);

JSBigInt(VM&, Structure*, unsigned length);
template<typename CellType, SubspaceAccess>
static IsoSubspace* subspaceFor(VM& vm)
{
return &vm.bigIntSpace;
}

enum class InitializationType { None, WithZero };
void initialize(InitializationType);
@@ -134,8 +142,8 @@ class JSBigInt final : public JSCell {
static JSBigInt* signedRightShift(JSGlobalObject*, JSBigInt* x, JSBigInt* y);

private:
JSBigInt(VM&, Structure*, Digit*, unsigned length);

using Digit = UCPURegister;
static constexpr unsigned bitsPerByte = 8;
static constexpr unsigned digitBits = sizeof(Digit) * bitsPerByte;
static constexpr unsigned halfDigitBits = digitBits / 2;
@@ -233,32 +241,21 @@ class JSBigInt final : public JSCell {

static Optional<Digit> toShiftAmount(JSBigInt* x);

inline static size_t allocationSize(unsigned length);
inline static size_t offsetOfData()
{
return WTF::roundUpToMultipleOf<sizeof(Digit)>(sizeof(JSBigInt));
return OBJECT_OFFSETOF(JSBigInt, m_data);
}

inline Digit* dataStorage()
{
return bitwise_cast<Digit*>(reinterpret_cast<char*>(this) + offsetOfData());
}
inline Digit* dataStorage() { return m_data.get(m_length); }

Digit digit(unsigned);
void setDigit(unsigned, Digit);

const unsigned m_length;
bool m_sign { false };

friend size_t cellSize(VM&, JSCell*);
CagedUniquePtr<Gigacage::Primitive, Digit> m_data;
};

inline size_t JSBigInt::allocationSize(unsigned length)
{
size_t sizeWithPadding = WTF::roundUpToMultipleOf<sizeof(size_t)>(sizeof(JSBigInt));
return sizeWithPadding + length * sizeof(Digit);
}

inline JSBigInt* asBigInt(JSValue value)
{
ASSERT(value.asCell()->isBigInt());
@@ -276,6 +276,7 @@ VM::VM(VMType vmType, HeapType heapType)
, variableSizedCellSpace("Variable Sized JSCell", heap, cellHeapCellType.get(), fastMallocAllocator.get()) // Hash:0xbcd769cc
, destructibleCellSpace("Destructible JSCell", heap, destructibleCellHeapCellType.get(), fastMallocAllocator.get()) // Hash:0xbfff3d73
, destructibleObjectSpace("JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get()) // Hash:0x4f5ed7a9
, bigIntSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), JSBigInt)
, executableToCodeBlockEdgeSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), ExecutableToCodeBlockEdge) // Hash:0x7b730b20
, functionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSFunction) // Hash:0x800fca72
, getterSetterSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), GetterSetter)
@@ -376,6 +376,7 @@ class VM : public ThreadSafeRefCounted<VM>, public DoublyLinkedListNode<VM> {
CompleteSubspace destructibleCellSpace;
CompleteSubspace destructibleObjectSpace;

IsoSubspace bigIntSpace;
IsoSubspace executableToCodeBlockEdgeSpace;
IsoSubspace functionSpace;
IsoSubspace getterSetterSpace;

0 comments on commit 3e0ce76

Please sign in to comment.