Commit 5965c90b authored by Darius M's avatar Darius M Committed by V8 LUCI CQ

Move some string allocation functions from Factory to FactoryBase

In a subsequent CL, I'll need to do String allocations in Turbofan (in
the background), where only a LocalFactory is available. By moving
those string allocation functions to FactoryBase, they will also be
available in the LocalFactory.

Change-Id: I066bbd4b5016645de183633ef237986e0ae50f5d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3811581Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82262}
parent 9f0d20b0
......@@ -16,6 +16,14 @@
namespace v8 {
namespace internal {
#define ROOT_ACCESSOR(Type, name, CamelName) \
template <typename Impl> \
Handle<Type> FactoryBase<Impl>::name() { \
return read_only_roots().name##_handle(); \
}
READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
template <typename Impl>
Handle<Oddball> FactoryBase<Impl>::ToBoolean(bool value) {
return value ? impl()->true_value() : impl()->false_value();
......
......@@ -27,6 +27,7 @@
#include "src/objects/string.h"
#include "src/objects/swiss-name-dictionary-inl.h"
#include "src/objects/template-objects-inl.h"
#include "src/roots/roots.h"
namespace v8 {
namespace internal {
......@@ -818,6 +819,144 @@ Handle<String> FactoryBase<Impl>::NewConsString(Handle<String> left,
return handle(result, isolate());
}
template <typename Impl>
Handle<String> FactoryBase<Impl>::LookupSingleCharacterStringFromCode(
uint16_t code) {
if (code <= unibrow::Latin1::kMaxChar) {
DisallowGarbageCollection no_gc;
Object value = single_character_string_table()->get(code);
DCHECK_NE(value, *undefined_value());
return handle(String::cast(value), isolate());
}
uint16_t buffer[] = {code};
return InternalizeString(base::Vector<const uint16_t>(buffer, 1));
}
template <typename Impl>
MaybeHandle<String> FactoryBase<Impl>::NewStringFromOneByte(
const base::Vector<const uint8_t>& string, AllocationType allocation) {
DCHECK_NE(allocation, AllocationType::kReadOnly);
int length = string.length();
if (length == 0) return empty_string();
if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
Handle<SeqOneByteString> result;
ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
NewRawOneByteString(string.length(), allocation),
String);
DisallowGarbageCollection no_gc;
// Copy the characters into the new object.
// SharedStringAccessGuardIfNeeded is NotNeeded because {result} is freshly
// allocated and hasn't escaped the factory yet, so it can't be concurrently
// accessed.
CopyChars(SeqOneByteString::cast(*result).GetChars(
no_gc, SharedStringAccessGuardIfNeeded::NotNeeded()),
string.begin(), length);
return result;
}
namespace {
template <typename Impl>
V8_INLINE Handle<String> CharToString(FactoryBase<Impl>* factory,
const char* string,
NumberCacheMode mode) {
// We tenure the allocated string since it is referenced from the
// number-string cache which lives in the old space.
AllocationType type = mode == NumberCacheMode::kIgnore
? AllocationType::kYoung
: AllocationType::kOld;
return factory->NewStringFromAsciiChecked(string, type);
}
} // namespace
template <typename Impl>
Handle<String> FactoryBase<Impl>::NumberToString(Handle<Object> number,
NumberCacheMode mode) {
SLOW_DCHECK(number->IsNumber());
if (number->IsSmi()) return SmiToString(Smi::cast(*number), mode);
double double_value = Handle<HeapNumber>::cast(number)->value();
// Try to canonicalize doubles.
int smi_value;
if (DoubleToSmiInteger(double_value, &smi_value)) {
return SmiToString(Smi::FromInt(smi_value), mode);
}
return HeapNumberToString(Handle<HeapNumber>::cast(number), double_value,
mode);
}
template <typename Impl>
Handle<String> FactoryBase<Impl>::HeapNumberToString(Handle<HeapNumber> number,
double value,
NumberCacheMode mode) {
int hash = mode == NumberCacheMode::kIgnore
? 0
: impl()->NumberToStringCacheHash(value);
if (mode == NumberCacheMode::kBoth) {
Handle<Object> cached = impl()->NumberToStringCacheGet(*number, hash);
if (!cached->IsUndefined(isolate())) return Handle<String>::cast(cached);
}
Handle<String> result;
if (value == 0) {
result = zero_string();
} else if (std::isnan(value)) {
result = NaN_string();
} else {
char arr[kNumberToStringBufferSize];
base::Vector<char> buffer(arr, arraysize(arr));
const char* string = DoubleToCString(value, buffer);
result = CharToString(this, string, mode);
}
if (mode != NumberCacheMode::kIgnore) {
impl()->NumberToStringCacheSet(number, hash, result);
}
return result;
}
template <typename Impl>
inline Handle<String> FactoryBase<Impl>::SmiToString(Smi number,
NumberCacheMode mode) {
int hash = mode == NumberCacheMode::kIgnore
? 0
: impl()->NumberToStringCacheHash(number);
if (mode == NumberCacheMode::kBoth) {
Handle<Object> cached = impl()->NumberToStringCacheGet(number, hash);
if (!cached->IsUndefined(isolate())) return Handle<String>::cast(cached);
}
Handle<String> result;
if (number == Smi::zero()) {
result = zero_string();
} else {
char arr[kNumberToStringBufferSize];
base::Vector<char> buffer(arr, arraysize(arr));
const char* string = IntToCString(number.value(), buffer);
result = CharToString(this, string, mode);
}
if (mode != NumberCacheMode::kIgnore) {
impl()->NumberToStringCacheSet(handle(number, isolate()), hash, result);
}
// Compute the hash here (rather than letting the caller take care of it) so
// that the "cache hit" case above doesn't have to bother with it.
static_assert(Smi::kMaxValue <= std::numeric_limits<uint32_t>::max());
{
DisallowGarbageCollection no_gc;
String raw = *result;
if (raw.raw_hash_field() == String::kEmptyHashField &&
number.value() >= 0) {
uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash(
static_cast<uint32_t>(number.value()), raw.length());
raw.set_raw_hash_field(raw_hash_field);
}
}
return result;
}
template <typename Impl>
Handle<FreshlyAllocatedBigInt> FactoryBase<Impl>::NewBigInt(
int length, AllocationType allocation) {
......
......@@ -47,6 +47,8 @@ class ValueType;
template <typename Impl>
class FactoryBase;
enum class NumberCacheMode { kIgnore, kSetOnly, kBoth };
// Putting Torque-generated definitions in a superclass allows to shadow them
// easily when they shouldn't be used and to reference them when they happen to
// have the same signature.
......@@ -60,12 +62,15 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) TorqueGeneratedFactory {
};
template <typename Impl>
class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
: public TorqueGeneratedFactory<Impl> {
class FactoryBase : public TorqueGeneratedFactory<Impl> {
public:
// Converts the given boolean condition to JavaScript boolean value.
inline Handle<Oddball> ToBoolean(bool value);
#define ROOT_ACCESSOR(Type, name, CamelName) inline Handle<Type> name();
READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
// Numbers (e.g. literals) are pretenured by the parser.
// The return value may be a smi or a heap number.
template <AllocationType allocation = AllocationType::kYoung>
......@@ -221,6 +226,20 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
Handle<SeqTwoByteString> AllocateRawTwoByteInternalizedString(
int length, uint32_t raw_hash_field);
// Creates a single character string where the character has given code.
// A cache is used for Latin1 codes.
Handle<String> LookupSingleCharacterStringFromCode(uint16_t code);
MaybeHandle<String> NewStringFromOneByte(
const base::Vector<const uint8_t>& string,
AllocationType allocation = AllocationType::kYoung);
inline Handle<String> NewStringFromAsciiChecked(
const char* str, AllocationType allocation = AllocationType::kYoung) {
return NewStringFromOneByte(base::OneByteVector(str), allocation)
.ToHandleChecked();
}
// Allocates and partially initializes an one-byte or two-byte String. The
// characters of the string are uninitialized. Currently used in regexp code
// only, where they are pretenured.
......@@ -237,6 +256,14 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
Handle<String> left, Handle<String> right, int length, bool one_byte,
AllocationType allocation = AllocationType::kYoung);
V8_WARN_UNUSED_RESULT Handle<String> NumberToString(
Handle<Object> number, NumberCacheMode mode = NumberCacheMode::kBoth);
V8_WARN_UNUSED_RESULT Handle<String> HeapNumberToString(
Handle<HeapNumber> number, double value,
NumberCacheMode mode = NumberCacheMode::kBoth);
V8_WARN_UNUSED_RESULT Handle<String> SmiToString(
Smi number, NumberCacheMode mode = NumberCacheMode::kBoth);
V8_WARN_UNUSED_RESULT MaybeHandle<SeqOneByteString> NewRawSharedOneByteString(
int length);
V8_WARN_UNUSED_RESULT MaybeHandle<SeqTwoByteString> NewRawSharedTwoByteString(
......@@ -274,6 +301,9 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
AllocationType allocation, Map string_map);
protected:
// Must be large enough to fit any double, int, or size_t.
static constexpr int kNumberToStringBufferSize = 32;
// Allocate memory for an uninitialized array (e.g., a FixedArray or similar).
HeapObject AllocateRawArray(int size, AllocationType allocation);
HeapObject AllocateRawFixedArray(int length, AllocationType allocation);
......@@ -318,6 +348,11 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
friend TorqueGeneratedFactory<Impl>;
};
extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
FactoryBase<Factory>;
extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
FactoryBase<LocalFactory>;
} // namespace internal
} // namespace v8
......
......@@ -27,7 +27,7 @@ namespace internal {
Handle<Type> Factory::name() { \
return Handle<Type>(&isolate()->roots_table()[RootIndex::k##CamelName]); \
}
ROOT_LIST(ROOT_ACCESSOR)
MUTABLE_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
bool Factory::CodeBuilder::CompiledWithConcurrentBaseline() const {
......@@ -89,6 +89,35 @@ Factory::CodeBuilder& Factory::CodeBuilder::set_interpreter_data(
return *this;
}
void Factory::NumberToStringCacheSet(Handle<Object> number, int hash,
Handle<String> js_string) {
if (!number_string_cache()->get(hash * 2).IsUndefined(isolate()) &&
!FLAG_optimize_for_size) {
int full_size = isolate()->heap()->MaxNumberToStringCacheSize();
if (number_string_cache()->length() != full_size) {
Handle<FixedArray> new_cache =
NewFixedArray(full_size, AllocationType::kOld);
isolate()->heap()->set_number_string_cache(*new_cache);
return;
}
}
DisallowGarbageCollection no_gc;
FixedArray cache = *number_string_cache();
cache.set(hash * 2, *number);
cache.set(hash * 2 + 1, *js_string);
}
Handle<Object> Factory::NumberToStringCacheGet(Object number, int hash) {
DisallowGarbageCollection no_gc;
FixedArray cache = *number_string_cache();
Object key = cache.get(hash * 2);
if (key == number || (key.IsHeapNumber() && number.IsHeapNumber() &&
key.Number() == number.Number())) {
return Handle<String>(String::cast(cache.get(hash * 2 + 1)), isolate());
}
return undefined_value();
}
} // namespace internal
} // namespace v8
......
......@@ -683,24 +683,6 @@ template Handle<String> Factory::InternalizeString(
Handle<SeqTwoByteString> string, int from, int length,
bool convert_encoding);
MaybeHandle<String> Factory::NewStringFromOneByte(
const base::Vector<const uint8_t>& string, AllocationType allocation) {
DCHECK_NE(allocation, AllocationType::kReadOnly);
int length = string.length();
if (length == 0) return empty_string();
if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
Handle<SeqOneByteString> result;
ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
NewRawOneByteString(string.length(), allocation),
String);
DisallowGarbageCollection no_gc;
// Copy the characters into the new object.
CopyChars(SeqOneByteString::cast(*result).GetChars(no_gc), string.begin(),
length);
return result;
}
namespace {
void ThrowInvalidEncodedStringBytes(Isolate* isolate, MessageTemplate message) {
#if V8_ENABLE_WEBASSEMBLY
......@@ -1058,17 +1040,6 @@ StringTransitionStrategy Factory::ComputeSharingStrategyForString(
}
}
Handle<String> Factory::LookupSingleCharacterStringFromCode(uint16_t code) {
if (code <= unibrow::Latin1::kMaxChar) {
DisallowGarbageCollection no_gc;
Object value = single_character_string_table()->get(code);
DCHECK_NE(value, *undefined_value());
return handle(String::cast(value), isolate());
}
uint16_t buffer[] = {code};
return InternalizeString(base::Vector<const uint16_t>(buffer, 1));
}
Handle<String> Factory::NewSurrogatePairString(uint16_t lead, uint16_t trail) {
DCHECK_GE(lead, 0xD800);
DCHECK_LE(lead, 0xDBFF);
......@@ -3376,141 +3347,17 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForWebSnapshot() {
FunctionKind::kNormalFunction);
}
namespace {
V8_INLINE int NumberToStringCacheHash(Handle<FixedArray> cache, Smi number) {
int mask = (cache->length() >> 1) - 1;
int Factory::NumberToStringCacheHash(Smi number) {
int mask = (number_string_cache()->length() >> 1) - 1;
return number.value() & mask;
}
V8_INLINE int NumberToStringCacheHash(Handle<FixedArray> cache, double number) {
int mask = (cache->length() >> 1) - 1;
int Factory::NumberToStringCacheHash(double number) {
int mask = (number_string_cache()->length() >> 1) - 1;
int64_t bits = base::bit_cast<int64_t>(number);
return (static_cast<int>(bits) ^ static_cast<int>(bits >> 32)) & mask;
}
V8_INLINE Handle<String> CharToString(Factory* factory, const char* string,
NumberCacheMode mode) {
// We tenure the allocated string since it is referenced from the
// number-string cache which lives in the old space.
AllocationType type = mode == NumberCacheMode::kIgnore
? AllocationType::kYoung
: AllocationType::kOld;
return factory->NewStringFromAsciiChecked(string, type);
}
} // namespace
void Factory::NumberToStringCacheSet(Handle<Object> number, int hash,
Handle<String> js_string) {
if (!number_string_cache()->get(hash * 2).IsUndefined(isolate()) &&
!FLAG_optimize_for_size) {
int full_size = isolate()->heap()->MaxNumberToStringCacheSize();
if (number_string_cache()->length() != full_size) {
Handle<FixedArray> new_cache =
NewFixedArray(full_size, AllocationType::kOld);
isolate()->heap()->set_number_string_cache(*new_cache);
return;
}
}
DisallowGarbageCollection no_gc;
FixedArray cache = *number_string_cache();
cache.set(hash * 2, *number);
cache.set(hash * 2 + 1, *js_string);
}
Handle<Object> Factory::NumberToStringCacheGet(Object number, int hash) {
DisallowGarbageCollection no_gc;
FixedArray cache = *number_string_cache();
Object key = cache.get(hash * 2);
if (key == number || (key.IsHeapNumber() && number.IsHeapNumber() &&
key.Number() == number.Number())) {
return Handle<String>(String::cast(cache.get(hash * 2 + 1)), isolate());
}
return undefined_value();
}
Handle<String> Factory::NumberToString(Handle<Object> number,
NumberCacheMode mode) {
SLOW_DCHECK(number->IsNumber());
if (number->IsSmi()) return SmiToString(Smi::cast(*number), mode);
double double_value = Handle<HeapNumber>::cast(number)->value();
// Try to canonicalize doubles.
int smi_value;
if (DoubleToSmiInteger(double_value, &smi_value)) {
return SmiToString(Smi::FromInt(smi_value), mode);
}
return HeapNumberToString(Handle<HeapNumber>::cast(number), double_value,
mode);
}
// Must be large enough to fit any double, int, or size_t.
static const int kNumberToStringBufferSize = 32;
Handle<String> Factory::HeapNumberToString(Handle<HeapNumber> number,
double value, NumberCacheMode mode) {
int hash = 0;
if (mode != NumberCacheMode::kIgnore) {
hash = NumberToStringCacheHash(number_string_cache(), value);
}
if (mode == NumberCacheMode::kBoth) {
Handle<Object> cached = NumberToStringCacheGet(*number, hash);
if (!cached->IsUndefined(isolate())) return Handle<String>::cast(cached);
}
Handle<String> result;
if (value == 0) {
result = zero_string();
} else if (std::isnan(value)) {
result = NaN_string();
} else {
char arr[kNumberToStringBufferSize];
base::Vector<char> buffer(arr, arraysize(arr));
const char* string = DoubleToCString(value, buffer);
result = CharToString(this, string, mode);
}
if (mode != NumberCacheMode::kIgnore) {
NumberToStringCacheSet(number, hash, result);
}
return result;
}
inline Handle<String> Factory::SmiToString(Smi number, NumberCacheMode mode) {
int hash = NumberToStringCacheHash(number_string_cache(), number);
if (mode == NumberCacheMode::kBoth) {
Handle<Object> cached = NumberToStringCacheGet(number, hash);
if (!cached->IsUndefined(isolate())) return Handle<String>::cast(cached);
}
Handle<String> result;
if (number == Smi::zero()) {
result = zero_string();
} else {
char arr[kNumberToStringBufferSize];
base::Vector<char> buffer(arr, arraysize(arr));
const char* string = IntToCString(number.value(), buffer);
result = CharToString(this, string, mode);
}
if (mode != NumberCacheMode::kIgnore) {
NumberToStringCacheSet(handle(number, isolate()), hash, result);
}
// Compute the hash here (rather than letting the caller take care of it) so
// that the "cache hit" case above doesn't have to bother with it.
static_assert(Smi::kMaxValue <= std::numeric_limits<uint32_t>::max());
{
DisallowGarbageCollection no_gc;
String raw = *result;
if (raw.raw_hash_field() == String::kEmptyHashField &&
number.value() >= 0) {
uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash(
static_cast<uint32_t>(number.value()), raw.length());
raw.set_raw_hash_field(raw_hash_field);
}
}
return result;
}
Handle<String> Factory::SizeToString(size_t value, bool check_cache) {
Handle<String> result;
NumberCacheMode cache_mode =
......
......@@ -112,8 +112,6 @@ enum FunctionMode {
kWithReadonlyPrototypeBit | kWithNameBit,
};
enum class NumberCacheMode { kIgnore, kSetOnly, kBoth };
// Interface for handle based allocation.
class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
public:
......@@ -228,9 +226,9 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
// two-byte. One should choose between the three string factory functions
// based on the encoding of the string buffer that the string is
// initialized from.
// - ...FromOneByte initializes the string from a buffer that is Latin1
// encoded (it does not check that the buffer is Latin1 encoded) and
// the result will be Latin1 encoded.
// - ...FromOneByte (defined in FactoryBase) initializes the string from a
// buffer that is Latin1 encoded (it does not check that the buffer is
// Latin1 encoded) and the result will be Latin1 encoded.
// - ...FromUtf8 initializes the string from a buffer that is UTF-8
// encoded. If the characters are all ASCII characters, the result
// will be Latin1 encoded, otherwise it will converted to two-byte.
......@@ -239,10 +237,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
// will be converted to Latin1, otherwise it will be left as two-byte.
//
// One-byte strings are pretenured when used as keys in the SourceCodeCache.
V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromOneByte(
const base::Vector<const uint8_t>& str,
AllocationType allocation = AllocationType::kYoung);
template <size_t N>
inline Handle<String> NewStringFromStaticChars(
const char (&str)[N],
......@@ -341,10 +335,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
ComputeSharingStrategyForString(Handle<String> string,
MaybeHandle<Map>* shared_map);
// Creates a single character string where the character has given code.
// A cache is used for Latin1 codes.
Handle<String> LookupSingleCharacterStringFromCode(uint16_t code);
// Create or lookup a single character string made up of a utf16 surrogate
// pair.
Handle<String> NewSurrogatePairString(uint16_t lead, uint16_t trail);
......@@ -787,14 +777,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
DECLARE_ERROR(WasmExceptionError)
#undef DECLARE_ERROR
Handle<String> NumberToString(Handle<Object> number,
NumberCacheMode mode = NumberCacheMode::kBoth);
Handle<String> SmiToString(Smi number,
NumberCacheMode mode = NumberCacheMode::kBoth);
Handle<String> HeapNumberToString(
Handle<HeapNumber> number, double value,
NumberCacheMode mode = NumberCacheMode::kBoth);
Handle<String> SizeToString(size_t value, bool check_cache = true);
inline Handle<String> Uint32ToString(uint32_t value,
bool check_cache = true) {
......@@ -802,7 +784,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
}
#define ROOT_ACCESSOR(Type, name, CamelName) inline Handle<Type> name();
ROOT_LIST(ROOT_ACCESSOR)
MUTABLE_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
// Allocates a new SharedFunctionInfo object.
......@@ -1133,6 +1115,10 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
MaybeHandle<String> NewStringFromTwoByte(const base::uc16* string, int length,
AllocationType allocation);
// Functions to get the hash of a number for the number_string_cache.
int NumberToStringCacheHash(Smi number);
int NumberToStringCacheHash(double number);
// Attempt to find the number in a small cache. If we finds it, return
// the string representation of the number. Otherwise return undefined.
V8_INLINE Handle<Object> NumberToStringCacheGet(Object number, int hash);
......
......@@ -133,6 +133,11 @@ RootsTable& Heap::roots_table() { return isolate()->roots_table(); }
MUTABLE_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
FixedArray Heap::single_character_string_table() {
return FixedArray::cast(
Object(roots_table()[RootIndex::kSingleCharacterStringTable]));
}
#define ROOT_ACCESSOR(type, name, CamelName) \
void Heap::set_##name(type value) { \
/* The deserializer makes use of the fact that these common roots are */ \
......
......@@ -939,6 +939,8 @@ class Heap {
MUTABLE_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
V8_INLINE FixedArray single_character_string_table();
V8_INLINE void SetRootMaterializedObjects(FixedArray objects);
V8_INLINE void SetRootScriptList(Object value);
V8_INLINE void SetRootNoScriptSharedFunctionInfos(Object value);
......
......@@ -12,13 +12,6 @@
namespace v8 {
namespace internal {
#define ROOT_ACCESSOR(Type, name, CamelName) \
Handle<Type> LocalFactory::name() { \
return read_only_roots().name##_handle(); \
}
READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
#define ACCESSOR_INFO_ACCESSOR(Type, name, CamelName) \
Handle<Type> LocalFactory::name() { \
/* Do a bit of handle location magic to cast the Handle without having */ \
......
......@@ -8,6 +8,7 @@
#include "src/execution/local-isolate.h"
#include "src/handles/handles.h"
#include "src/heap/concurrent-allocator-inl.h"
#include "src/heap/local-factory-inl.h"
#include "src/heap/local-heap-inl.h"
#include "src/numbers/hash-seed-inl.h"
#include "src/objects/fixed-array.h"
......@@ -51,5 +52,16 @@ HeapObject LocalFactory::AllocateRaw(int size, AllocationType allocation,
size, allocation, AllocationOrigin::kRuntime, alignment));
}
int LocalFactory::NumberToStringCacheHash(Smi) { return 0; }
int LocalFactory::NumberToStringCacheHash(double) { return 0; }
void LocalFactory::NumberToStringCacheSet(Handle<Object>, int, Handle<String>) {
}
Handle<Object> LocalFactory::NumberToStringCacheGet(Object, int) {
return undefined_value();
}
} // namespace internal
} // namespace v8
......@@ -33,7 +33,6 @@ class V8_EXPORT_PRIVATE LocalFactory : public FactoryBase<LocalFactory> {
ReadOnlyRoots read_only_roots() const { return roots_; }
#define ROOT_ACCESSOR(Type, name, CamelName) inline Handle<Type> name();
READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
// AccessorInfos appear mutable, but they're actually not mutated once they
// finish initializing. In particular, the root accessors are not mutated and
// are safe to access (as long as the off-thread job doesn't try to mutate
......@@ -48,6 +47,16 @@ class V8_EXPORT_PRIVATE LocalFactory : public FactoryBase<LocalFactory> {
UNREACHABLE();
}
// The LocalFactory does not have access to the number_string_cache (since
// it's a mutable root), but it still needs to define some cache-related
// method that are used by FactoryBase. Those method do basically nothing in
// the case of the LocalFactory.
int NumberToStringCacheHash(Smi number);
int NumberToStringCacheHash(double number);
void NumberToStringCacheSet(Handle<Object> number, int hash,
Handle<String> js_string);
Handle<Object> NumberToStringCacheGet(Object number, int hash);
private:
friend class FactoryBase<LocalFactory>;
......
......@@ -691,7 +691,7 @@ void Heap::CreateInitialObjects() {
// Allocate and initialize table for single character one byte strings.
int table_size = String::kMaxOneByteCharCode + 1;
set_single_character_string_table(
*factory->NewFixedArray(table_size, AllocationType::kOld));
*factory->NewFixedArray(table_size, AllocationType::kReadOnly));
for (int i = 0; i < table_size; ++i) {
uint8_t code = static_cast<uint8_t>(i);
Handle<String> str =
......
......@@ -23,6 +23,10 @@ template <typename T>
class Handle;
class Heap;
class Isolate;
class Factory;
template <typename Impl>
class FactoryBase;
class LocalFactory;
class Map;
class PropertyCell;
class ReadOnlyHeap;
......@@ -195,6 +199,8 @@ class Symbol;
V(HeapNumber, infinity_value, InfinityValue) \
V(HeapNumber, minus_zero_value, MinusZeroValue) \
V(HeapNumber, minus_infinity_value, MinusInfinityValue) \
/* Table of strings of one-byte single characters */ \
V(FixedArray, single_character_string_table, SingleCharacterStringTable) \
/* Marker for self-references during code-generation */ \
V(HeapObject, self_reference_marker, SelfReferenceMarker) \
/* Marker for basic-block usage counters array during code-generation */ \
......@@ -246,8 +252,6 @@ class Symbol;
/* Caches */ \
V(FixedArray, string_split_cache, StringSplitCache) \
V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \
/* Table of strings of one-byte single characters */ \
V(FixedArray, single_character_string_table, SingleCharacterStringTable) \
/* Indirection lists for isolate-independent builtins */ \
V(FixedArray, builtins_constants_table, BuiltinsConstantsTable) \
/* Internal SharedFunctionInfos */ \
......@@ -568,6 +572,8 @@ class RootsTable {
friend class Isolate;
friend class Heap;
friend class Factory;
friend class FactoryBase<Factory>;
friend class FactoryBase<LocalFactory>;
friend class PointerCompressedReadOnlyArtifacts;
friend class ReadOnlyHeap;
friend class ReadOnlyRoots;
......
......@@ -384,76 +384,76 @@ KNOWN_MAPS = {
("read_only_space", 0x033f1): (131, "BasicBlockCountersMarkerMap"),
("read_only_space", 0x03435): (146, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x03535): (159, "InterceptorInfoMap"),
("read_only_space", 0x05f81): (132, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05fa9): (133, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05fd1): (134, "CallableTaskMap"),
("read_only_space", 0x05ff9): (135, "CallbackTaskMap"),
("read_only_space", 0x06021): (136, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x06049): (139, "FunctionTemplateInfoMap"),
("read_only_space", 0x06071): (140, "ObjectTemplateInfoMap"),
("read_only_space", 0x06099): (141, "AccessCheckInfoMap"),
("read_only_space", 0x060c1): (142, "AccessorPairMap"),
("read_only_space", 0x060e9): (143, "AliasedArgumentsEntryMap"),
("read_only_space", 0x06111): (144, "AllocationMementoMap"),
("read_only_space", 0x06139): (147, "AsmWasmDataMap"),
("read_only_space", 0x06161): (148, "AsyncGeneratorRequestMap"),
("read_only_space", 0x06189): (149, "BreakPointMap"),
("read_only_space", 0x061b1): (150, "BreakPointInfoMap"),
("read_only_space", 0x061d9): (151, "CachedTemplateObjectMap"),
("read_only_space", 0x06201): (152, "CallSiteInfoMap"),
("read_only_space", 0x06229): (153, "ClassPositionsMap"),
("read_only_space", 0x06251): (154, "DebugInfoMap"),
("read_only_space", 0x06279): (156, "ErrorStackDataMap"),
("read_only_space", 0x062a1): (158, "FunctionTemplateRareDataMap"),
("read_only_space", 0x062c9): (160, "InterpreterDataMap"),
("read_only_space", 0x062f1): (161, "ModuleRequestMap"),
("read_only_space", 0x06319): (162, "PromiseCapabilityMap"),
("read_only_space", 0x06341): (163, "PromiseOnStackMap"),
("read_only_space", 0x06369): (164, "PromiseReactionMap"),
("read_only_space", 0x06391): (165, "PropertyDescriptorObjectMap"),
("read_only_space", 0x063b9): (166, "PrototypeInfoMap"),
("read_only_space", 0x063e1): (167, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x06409): (168, "ScriptMap"),
("read_only_space", 0x06431): (169, "ScriptOrModuleMap"),
("read_only_space", 0x06459): (170, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x06481): (171, "StackFrameInfoMap"),
("read_only_space", 0x064a9): (172, "TemplateObjectDescriptionMap"),
("read_only_space", 0x064d1): (173, "Tuple2Map"),
("read_only_space", 0x064f9): (174, "WasmExceptionTagMap"),
("read_only_space", 0x06521): (175, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x06549): (195, "SloppyArgumentsElementsMap"),
("read_only_space", 0x06571): (229, "DescriptorArrayMap"),
("read_only_space", 0x06599): (218, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x065c1): (216, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x065e9): (219, "UncompiledDataWithoutPreparseDataWithJobMap"),
("read_only_space", 0x06611): (217, "UncompiledDataWithPreparseDataAndJobMap"),
("read_only_space", 0x06639): (250, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x06661): (196, "TurbofanBitsetTypeMap"),
("read_only_space", 0x06689): (200, "TurbofanUnionTypeMap"),
("read_only_space", 0x066b1): (199, "TurbofanRangeTypeMap"),
("read_only_space", 0x066d9): (197, "TurbofanHeapConstantTypeMap"),
("read_only_space", 0x06701): (198, "TurbofanOtherNumberConstantTypeMap"),
("read_only_space", 0x06729): (246, "InternalClassMap"),
("read_only_space", 0x06751): (257, "SmiPairMap"),
("read_only_space", 0x06779): (256, "SmiBoxMap"),
("read_only_space", 0x067a1): (201, "ExportedSubClassBaseMap"),
("read_only_space", 0x067c9): (202, "ExportedSubClassMap"),
("read_only_space", 0x067f1): (227, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x06819): (228, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x06841): (194, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x06869): (247, "InternalClassWithStructElementsMap"),
("read_only_space", 0x06891): (203, "ExportedSubClass2Map"),
("read_only_space", 0x068b9): (258, "SortStateMap"),
("read_only_space", 0x068e1): (264, "WasmStringViewIterMap"),
("read_only_space", 0x06909): (145, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x06931): (145, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x069fd): (137, "LoadHandler1Map"),
("read_only_space", 0x06a25): (137, "LoadHandler2Map"),
("read_only_space", 0x06a4d): (137, "LoadHandler3Map"),
("read_only_space", 0x06a75): (138, "StoreHandler0Map"),
("read_only_space", 0x06a9d): (138, "StoreHandler1Map"),
("read_only_space", 0x06ac5): (138, "StoreHandler2Map"),
("read_only_space", 0x06aed): (138, "StoreHandler3Map"),
("read_only_space", 0x07359): (132, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x07381): (133, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x073a9): (134, "CallableTaskMap"),
("read_only_space", 0x073d1): (135, "CallbackTaskMap"),
("read_only_space", 0x073f9): (136, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x07421): (139, "FunctionTemplateInfoMap"),
("read_only_space", 0x07449): (140, "ObjectTemplateInfoMap"),
("read_only_space", 0x07471): (141, "AccessCheckInfoMap"),
("read_only_space", 0x07499): (142, "AccessorPairMap"),
("read_only_space", 0x074c1): (143, "AliasedArgumentsEntryMap"),
("read_only_space", 0x074e9): (144, "AllocationMementoMap"),
("read_only_space", 0x07511): (147, "AsmWasmDataMap"),
("read_only_space", 0x07539): (148, "AsyncGeneratorRequestMap"),
("read_only_space", 0x07561): (149, "BreakPointMap"),
("read_only_space", 0x07589): (150, "BreakPointInfoMap"),
("read_only_space", 0x075b1): (151, "CachedTemplateObjectMap"),
("read_only_space", 0x075d9): (152, "CallSiteInfoMap"),
("read_only_space", 0x07601): (153, "ClassPositionsMap"),
("read_only_space", 0x07629): (154, "DebugInfoMap"),
("read_only_space", 0x07651): (156, "ErrorStackDataMap"),
("read_only_space", 0x07679): (158, "FunctionTemplateRareDataMap"),
("read_only_space", 0x076a1): (160, "InterpreterDataMap"),
("read_only_space", 0x076c9): (161, "ModuleRequestMap"),
("read_only_space", 0x076f1): (162, "PromiseCapabilityMap"),
("read_only_space", 0x07719): (163, "PromiseOnStackMap"),
("read_only_space", 0x07741): (164, "PromiseReactionMap"),
("read_only_space", 0x07769): (165, "PropertyDescriptorObjectMap"),
("read_only_space", 0x07791): (166, "PrototypeInfoMap"),
("read_only_space", 0x077b9): (167, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x077e1): (168, "ScriptMap"),
("read_only_space", 0x07809): (169, "ScriptOrModuleMap"),
("read_only_space", 0x07831): (170, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x07859): (171, "StackFrameInfoMap"),
("read_only_space", 0x07881): (172, "TemplateObjectDescriptionMap"),
("read_only_space", 0x078a9): (173, "Tuple2Map"),
("read_only_space", 0x078d1): (174, "WasmExceptionTagMap"),
("read_only_space", 0x078f9): (175, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x07921): (195, "SloppyArgumentsElementsMap"),
("read_only_space", 0x07949): (229, "DescriptorArrayMap"),
("read_only_space", 0x07971): (218, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x07999): (216, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x079c1): (219, "UncompiledDataWithoutPreparseDataWithJobMap"),
("read_only_space", 0x079e9): (217, "UncompiledDataWithPreparseDataAndJobMap"),
("read_only_space", 0x07a11): (250, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x07a39): (196, "TurbofanBitsetTypeMap"),
("read_only_space", 0x07a61): (200, "TurbofanUnionTypeMap"),
("read_only_space", 0x07a89): (199, "TurbofanRangeTypeMap"),
("read_only_space", 0x07ab1): (197, "TurbofanHeapConstantTypeMap"),
("read_only_space", 0x07ad9): (198, "TurbofanOtherNumberConstantTypeMap"),
("read_only_space", 0x07b01): (246, "InternalClassMap"),
("read_only_space", 0x07b29): (257, "SmiPairMap"),
("read_only_space", 0x07b51): (256, "SmiBoxMap"),
("read_only_space", 0x07b79): (201, "ExportedSubClassBaseMap"),
("read_only_space", 0x07ba1): (202, "ExportedSubClassMap"),
("read_only_space", 0x07bc9): (227, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x07bf1): (228, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x07c19): (194, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x07c41): (247, "InternalClassWithStructElementsMap"),
("read_only_space", 0x07c69): (203, "ExportedSubClass2Map"),
("read_only_space", 0x07c91): (258, "SortStateMap"),
("read_only_space", 0x07cb9): (264, "WasmStringViewIterMap"),
("read_only_space", 0x07ce1): (145, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x07d09): (145, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x07dd5): (137, "LoadHandler1Map"),
("read_only_space", 0x07dfd): (137, "LoadHandler2Map"),
("read_only_space", 0x07e25): (137, "LoadHandler3Map"),
("read_only_space", 0x07e4d): (138, "StoreHandler0Map"),
("read_only_space", 0x07e75): (138, "StoreHandler1Map"),
("read_only_space", 0x07e9d): (138, "StoreHandler2Map"),
("read_only_space", 0x07ec5): (138, "StoreHandler3Map"),
("map_space", 0x02139): (2114, "ExternalMap"),
("map_space", 0x02161): (2118, "JSMessageObjectMap"),
}
......@@ -497,13 +497,14 @@ KNOWN_OBJECTS = {
("read_only_space", 0x03599): "InfinityValue",
("read_only_space", 0x035a5): "MinusZeroValue",
("read_only_space", 0x035b1): "MinusInfinityValue",
("read_only_space", 0x035bd): "SelfReferenceMarker",
("read_only_space", 0x035fd): "BasicBlockCountersMarker",
("read_only_space", 0x03641): "OffHeapTrampolineRelocationInfo",
("read_only_space", 0x0364d): "GlobalThisBindingScopeInfo",
("read_only_space", 0x0367d): "EmptyFunctionScopeInfo",
("read_only_space", 0x036a1): "NativeScopeInfo",
("read_only_space", 0x036b9): "HashSeed",
("read_only_space", 0x035bd): "SingleCharacterStringTable",
("read_only_space", 0x049c5): "SelfReferenceMarker",
("read_only_space", 0x04a05): "BasicBlockCountersMarker",
("read_only_space", 0x04a49): "OffHeapTrampolineRelocationInfo",
("read_only_space", 0x04a55): "GlobalThisBindingScopeInfo",
("read_only_space", 0x04a85): "EmptyFunctionScopeInfo",
("read_only_space", 0x04aa9): "NativeScopeInfo",
("read_only_space", 0x04ac1): "HashSeed",
("old_space", 0x04221): "ArgumentsIteratorAccessor",
("old_space", 0x04249): "ArrayLengthAccessor",
("old_space", 0x04271): "BoundFunctionLengthAccessor",
......@@ -541,32 +542,31 @@ KNOWN_OBJECTS = {
("old_space", 0x04611): "StringIteratorProtector",
("old_space", 0x04625): "StringSplitCache",
("old_space", 0x04a2d): "RegExpMultipleCache",
("old_space", 0x04e35): "SingleCharacterStringTable",
("old_space", 0x0523d): "BuiltinsConstantsTable",
("old_space", 0x05681): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x056a5): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x056c9): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x056ed): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x05711): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x05735): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x05759): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x0577d): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x057a1): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x057c5): "PromiseAllResolveElementSharedFun",
("old_space", 0x057e9): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x0580d): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x05831): "PromiseAnyRejectElementSharedFun",
("old_space", 0x05855): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x05879): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x0589d): "PromiseCatchFinallySharedFun",
("old_space", 0x058c1): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x058e5): "PromiseThenFinallySharedFun",
("old_space", 0x05909): "PromiseThrowerFinallySharedFun",
("old_space", 0x0592d): "PromiseValueThunkFinallySharedFun",
("old_space", 0x05951): "ProxyRevokeSharedFun",
("old_space", 0x05975): "ShadowRealmImportValueFulfilledSFI",
("old_space", 0x05999): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
("old_space", 0x059bd): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
("old_space", 0x04e35): "BuiltinsConstantsTable",
("old_space", 0x05279): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x0529d): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x052c1): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x052e5): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x05309): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x0532d): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x05351): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x05375): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x05399): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x053bd): "PromiseAllResolveElementSharedFun",
("old_space", 0x053e1): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x05405): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x05429): "PromiseAnyRejectElementSharedFun",
("old_space", 0x0544d): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x05471): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x05495): "PromiseCatchFinallySharedFun",
("old_space", 0x054b9): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x054dd): "PromiseThenFinallySharedFun",
("old_space", 0x05501): "PromiseThrowerFinallySharedFun",
("old_space", 0x05525): "PromiseValueThunkFinallySharedFun",
("old_space", 0x05549): "ProxyRevokeSharedFun",
("old_space", 0x0556d): "ShadowRealmImportValueFulfilledSFI",
("old_space", 0x05591): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
("old_space", 0x055b5): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
}
# Lower 32 bits of first page addresses for various heap spaces.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment