mirror of
https://github.com/RGBCube/serenity
synced 2025-05-15 03:34:59 +00:00

This patch adds two macros to declare per-type allocators: - JS_DECLARE_ALLOCATOR(TypeName) - JS_DEFINE_ALLOCATOR(TypeName) When used, they add a type-specific CellAllocator that the Heap will delegate allocation requests to. The result of this is that GC objects of the same type always end up within the same HeapBlock, drastically reducing the ability to perform type confusion attacks. It also improves HeapBlock utilization, since each block now has cells sized exactly to the type used within that block. (Previously we only had a handful of block sizes available, and most GC allocations ended up with a large amount of slack in their tails.) There is a small performance hit from this, but I'm sure we can make up for it elsewhere. Note that the old size-based allocators still exist, and we fall back to them for any type that doesn't have its own CellAllocator.
58 lines
2.6 KiB
C++
58 lines
2.6 KiB
C++
/*
|
||
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
|
||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||
*
|
||
* SPDX-License-Identifier: BSD-2-Clause
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include <AK/Optional.h>
|
||
#include <AK/Variant.h>
|
||
#include <LibJS/Runtime/BigInt.h>
|
||
#include <LibJS/Runtime/Completion.h>
|
||
#include <LibJS/Runtime/Object.h>
|
||
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
|
||
|
||
namespace JS::Temporal {
|
||
|
||
class Instant final : public Object {
|
||
JS_OBJECT(Instant, Object);
|
||
JS_DECLARE_ALLOCATOR(Instant);
|
||
|
||
public:
|
||
virtual ~Instant() override = default;
|
||
|
||
[[nodiscard]] BigInt const& nanoseconds() const { return m_nanoseconds; }
|
||
|
||
private:
|
||
Instant(BigInt const& nanoseconds, Object& prototype);
|
||
|
||
virtual void visit_edges(Visitor&) override;
|
||
|
||
// 8.4 Properties of Temporal.Instant Instances, https://tc39.es/proposal-temporal/#sec-properties-of-temporal-instant-instances
|
||
NonnullGCPtr<BigInt const> m_nanoseconds; // [[Nanoseconds]]
|
||
};
|
||
|
||
// https://tc39.es/proposal-temporal/#eqn-nsMaxInstant
|
||
// nsMaxInstant = 10^8 × nsPerDay = 8.64 × 10^21
|
||
static auto const ns_max_instant = "8640000000000000000000"_sbigint;
|
||
|
||
// https://tc39.es/proposal-temporal/#eqn-nsMinInstant
|
||
// nsMinInstant = -nsMaxInstant = -8.64 × 10^21
|
||
static auto const ns_min_instant = "-8640000000000000000000"_sbigint;
|
||
|
||
bool is_valid_epoch_nanoseconds(BigInt const& epoch_nanoseconds);
|
||
bool is_valid_epoch_nanoseconds(Crypto::SignedBigInteger const& epoch_nanoseconds);
|
||
ThrowCompletionOr<Instant*> create_temporal_instant(VM&, BigInt const& nanoseconds, FunctionObject const* new_target = nullptr);
|
||
ThrowCompletionOr<Instant*> to_temporal_instant(VM&, Value item);
|
||
ThrowCompletionOr<BigInt*> parse_temporal_instant(VM&, StringView iso_string);
|
||
i32 compare_epoch_nanoseconds(BigInt const&, BigInt const&);
|
||
ThrowCompletionOr<BigInt*> add_instant(VM&, BigInt const& epoch_nanoseconds, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds);
|
||
BigInt* difference_instant(VM&, BigInt const& nanoseconds1, BigInt const& nanoseconds2, u64 rounding_increment, StringView smallest_unit, StringView rounding_mode);
|
||
BigInt* round_temporal_instant(VM&, BigInt const& nanoseconds, u64 increment, StringView unit, StringView rounding_mode);
|
||
ThrowCompletionOr<String> temporal_instant_to_string(VM&, Instant&, Value time_zone, Variant<StringView, u8> const& precision);
|
||
ThrowCompletionOr<Duration*> difference_temporal_instant(VM&, DifferenceOperation, Instant const&, Value other, Value options);
|
||
ThrowCompletionOr<Instant*> add_duration_to_or_subtract_duration_from_instant(VM&, ArithmeticOperation, Instant const&, Value temporal_duration_like);
|
||
|
||
}
|