Commit 588f3b37 authored by Darius Mercadier's avatar Darius Mercadier Committed by V8 LUCI CQ

Revert "Move some string allocation functions from Factory to FactoryBase"

This reverts commit 5965c90b.

Reason for revert: breaks tree

Original change's description:
> 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/+/3811581
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#82262}

Change-Id: I27b4dd06286562ec67e5e6e681e6bcebbff08980
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3816662
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Owners-Override: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82264}
parent 1067c6ac
......@@ -16,14 +16,6 @@
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,7 +27,6 @@
#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 {
......@@ -819,144 +818,6 @@ 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,8 +47,6 @@ 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.
......@@ -62,15 +60,12 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) TorqueGeneratedFactory {
};
template <typename Impl>
class FactoryBase : public TorqueGeneratedFactory<Impl> {
class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 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>
......@@ -226,20 +221,6 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {
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.
......@@ -256,14 +237,6 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {
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(
......@@ -301,9 +274,6 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {
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);
......@@ -348,11 +318,6 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {
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]); \
}
MUTABLE_ROOT_LIST(ROOT_ACCESSOR)
ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
bool Factory::CodeBuilder::CompiledWithConcurrentBaseline() const {
......@@ -89,35 +89,6 @@ 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,6 +683,24 @@ 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
......@@ -1040,6 +1058,17 @@ 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);
......@@ -3301,17 +3330,141 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForWebSnapshot() {
FunctionKind::kNormalFunction);
}
int Factory::NumberToStringCacheHash(Smi number) {
int mask = (number_string_cache()->length() >> 1) - 1;
namespace {
V8_INLINE int NumberToStringCacheHash(Handle<FixedArray> cache, Smi number) {
int mask = (cache->length() >> 1) - 1;
return number.value() & mask;
}
int Factory::NumberToStringCacheHash(double number) {
int mask = (number_string_cache()->length() >> 1) - 1;
V8_INLINE int NumberToStringCacheHash(Handle<FixedArray> cache, double number) {
int mask = (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,6 +112,8 @@ enum FunctionMode {
kWithReadonlyPrototypeBit | kWithNameBit,
};
enum class NumberCacheMode { kIgnore, kSetOnly, kBoth };
// Interface for handle based allocation.
class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
public:
......@@ -226,9 +228,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 (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.
// - ...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.
// - ...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.
......@@ -237,6 +239,10 @@ 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],
......@@ -335,6 +341,10 @@ 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);
......@@ -775,6 +785,14 @@ 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) {
......@@ -782,7 +800,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
}
#define ROOT_ACCESSOR(Type, name, CamelName) inline Handle<Type> name();
MUTABLE_ROOT_LIST(ROOT_ACCESSOR)
ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
// Allocates a new SharedFunctionInfo object.
......@@ -1113,10 +1131,6 @@ 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,11 +133,6 @@ 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,8 +939,6 @@ 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,6 +12,13 @@
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,7 +8,6 @@
#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"
......@@ -52,16 +51,5 @@ 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,6 +33,7 @@ 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
......@@ -47,16 +48,6 @@ 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::kReadOnly));
*factory->NewFixedArray(table_size, AllocationType::kOld));
for (int i = 0; i < table_size; ++i) {
uint8_t code = static_cast<uint8_t>(i);
Handle<String> str =
......
......@@ -23,10 +23,6 @@ template <typename T>
class Handle;
class Heap;
class Isolate;
class Factory;
template <typename Impl>
class FactoryBase;
class LocalFactory;
class Map;
class PropertyCell;
class ReadOnlyHeap;
......@@ -199,8 +195,6 @@ 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 */ \
......@@ -252,6 +246,8 @@ 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 */ \
......@@ -570,8 +566,6 @@ 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;
......
This diff is collapsed.
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