Handlifying clients of StringTable, step 1.
R=yangguo@chromium.org Review URL: https://codereview.chromium.org/239113002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20772 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b9a7b0bddc
commit
be29476f64
@ -37,6 +37,16 @@ Handle<Box> Factory::NewBox(Handle<Object> value) {
|
||||
}
|
||||
|
||||
|
||||
Handle<Oddball> Factory::NewOddball(Handle<Map> map,
|
||||
const char* to_string,
|
||||
Handle<Object> to_number,
|
||||
byte kind) {
|
||||
Handle<Oddball> oddball = New<Oddball>(map, OLD_POINTER_SPACE);
|
||||
Oddball::Initialize(isolate(), oddball, to_string, to_number, kind);
|
||||
return oddball;
|
||||
}
|
||||
|
||||
|
||||
Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) {
|
||||
ASSERT(0 <= size);
|
||||
CALL_HEAP_FUNCTION(
|
||||
|
@ -14,6 +14,11 @@ namespace internal {
|
||||
|
||||
class Factory V8_FINAL {
|
||||
public:
|
||||
Handle<Oddball> NewOddball(Handle<Map> map,
|
||||
const char* to_string,
|
||||
Handle<Object> to_number,
|
||||
byte kind);
|
||||
|
||||
// Allocates a fixed array initialized with undefined values.
|
||||
Handle<FixedArray> NewFixedArray(
|
||||
int size,
|
||||
|
208
src/heap.cc
208
src/heap.cc
@ -2759,18 +2759,6 @@ MaybeObject* Heap::AllocateAllocationSite() {
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::CreateOddball(Map* map,
|
||||
const char* to_string,
|
||||
Object* to_number,
|
||||
byte kind) {
|
||||
Object* result;
|
||||
{ MaybeObject* maybe_result = Allocate(map, OLD_POINTER_SPACE);
|
||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
||||
}
|
||||
return Oddball::cast(result)->Initialize(this, to_string, to_number, kind);
|
||||
}
|
||||
|
||||
|
||||
bool Heap::CreateApiObjects() {
|
||||
Object* obj;
|
||||
|
||||
@ -2843,116 +2831,83 @@ void Heap::CreateFixedStubs() {
|
||||
|
||||
|
||||
bool Heap::CreateInitialObjects() {
|
||||
Object* obj;
|
||||
HandleScope scope(isolate());
|
||||
Factory* factory = isolate()->factory();
|
||||
|
||||
// The -0 value must be set before NumberFromDouble works.
|
||||
{ MaybeObject* maybe_obj = AllocateHeapNumber(-0.0, TENURED);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_minus_zero_value(HeapNumber::cast(obj));
|
||||
set_minus_zero_value(*factory->NewHeapNumber(-0.0, TENURED));
|
||||
ASSERT(std::signbit(minus_zero_value()->Number()) != 0);
|
||||
|
||||
{ MaybeObject* maybe_obj = AllocateHeapNumber(OS::nan_value(), TENURED);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_nan_value(HeapNumber::cast(obj));
|
||||
|
||||
{ MaybeObject* maybe_obj = AllocateHeapNumber(V8_INFINITY, TENURED);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_infinity_value(HeapNumber::cast(obj));
|
||||
set_nan_value(*factory->NewHeapNumber(OS::nan_value(), TENURED));
|
||||
set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, TENURED));
|
||||
|
||||
// The hole has not been created yet, but we want to put something
|
||||
// predictable in the gaps in the string table, so lets make that Smi zero.
|
||||
set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0)));
|
||||
|
||||
// Allocate initial string table.
|
||||
{ MaybeObject* maybe_obj =
|
||||
StringTable::Allocate(this, kInitialStringTableSize);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
// Don't use set_string_table() due to asserts.
|
||||
roots_[kStringTableRootIndex] = obj;
|
||||
set_string_table(*StringTable::New(isolate(), kInitialStringTableSize));
|
||||
|
||||
// Finish initializing oddballs after creating the string table.
|
||||
{ MaybeObject* maybe_obj =
|
||||
undefined_value()->Initialize(this,
|
||||
"undefined",
|
||||
nan_value(),
|
||||
Oddball::kUndefined);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
Oddball::Initialize(isolate(),
|
||||
factory->undefined_value(),
|
||||
"undefined",
|
||||
factory->nan_value(),
|
||||
Oddball::kUndefined);
|
||||
|
||||
// Initialize the null_value.
|
||||
{ MaybeObject* maybe_obj = null_value()->Initialize(
|
||||
this, "null", Smi::FromInt(0), Oddball::kNull);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
Oddball::Initialize(isolate(),
|
||||
factory->null_value(),
|
||||
"null",
|
||||
handle(Smi::FromInt(0), isolate()),
|
||||
Oddball::kNull);
|
||||
|
||||
{ MaybeObject* maybe_obj = CreateOddball(boolean_map(),
|
||||
"true",
|
||||
Smi::FromInt(1),
|
||||
Oddball::kTrue);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_true_value(Oddball::cast(obj));
|
||||
set_true_value(*factory->NewOddball(factory->boolean_map(),
|
||||
"true",
|
||||
handle(Smi::FromInt(1), isolate()),
|
||||
Oddball::kTrue));
|
||||
|
||||
{ MaybeObject* maybe_obj = CreateOddball(boolean_map(),
|
||||
"false",
|
||||
Smi::FromInt(0),
|
||||
Oddball::kFalse);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_false_value(Oddball::cast(obj));
|
||||
set_false_value(*factory->NewOddball(factory->boolean_map(),
|
||||
"false",
|
||||
handle(Smi::FromInt(0), isolate()),
|
||||
Oddball::kFalse));
|
||||
|
||||
{ MaybeObject* maybe_obj = CreateOddball(the_hole_map(),
|
||||
"hole",
|
||||
Smi::FromInt(-1),
|
||||
Oddball::kTheHole);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_the_hole_value(Oddball::cast(obj));
|
||||
set_the_hole_value(*factory->NewOddball(factory->the_hole_map(),
|
||||
"hole",
|
||||
handle(Smi::FromInt(-1), isolate()),
|
||||
Oddball::kTheHole));
|
||||
|
||||
{ MaybeObject* maybe_obj = CreateOddball(uninitialized_map(),
|
||||
"uninitialized",
|
||||
Smi::FromInt(-1),
|
||||
Oddball::kUninitialized);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_uninitialized_value(Oddball::cast(obj));
|
||||
set_uninitialized_value(
|
||||
*factory->NewOddball(factory->uninitialized_map(),
|
||||
"uninitialized",
|
||||
handle(Smi::FromInt(-1), isolate()),
|
||||
Oddball::kUninitialized));
|
||||
|
||||
{ MaybeObject* maybe_obj = CreateOddball(arguments_marker_map(),
|
||||
"arguments_marker",
|
||||
Smi::FromInt(-4),
|
||||
Oddball::kArgumentMarker);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_arguments_marker(Oddball::cast(obj));
|
||||
set_arguments_marker(*factory->NewOddball(factory->arguments_marker_map(),
|
||||
"arguments_marker",
|
||||
handle(Smi::FromInt(-4), isolate()),
|
||||
Oddball::kArgumentMarker));
|
||||
|
||||
{ MaybeObject* maybe_obj = CreateOddball(no_interceptor_result_sentinel_map(),
|
||||
"no_interceptor_result_sentinel",
|
||||
Smi::FromInt(-2),
|
||||
Oddball::kOther);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_no_interceptor_result_sentinel(Oddball::cast(obj));
|
||||
set_no_interceptor_result_sentinel(
|
||||
*factory->NewOddball(factory->no_interceptor_result_sentinel_map(),
|
||||
"no_interceptor_result_sentinel",
|
||||
handle(Smi::FromInt(-2), isolate()),
|
||||
Oddball::kOther));
|
||||
|
||||
{ MaybeObject* maybe_obj = CreateOddball(termination_exception_map(),
|
||||
"termination_exception",
|
||||
Smi::FromInt(-3),
|
||||
Oddball::kOther);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_termination_exception(Oddball::cast(obj));
|
||||
set_termination_exception(
|
||||
*factory->NewOddball(factory->termination_exception_map(),
|
||||
"termination_exception",
|
||||
handle(Smi::FromInt(-3), isolate()),
|
||||
Oddball::kOther));
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(constant_string_table); i++) {
|
||||
{ MaybeObject* maybe_obj =
|
||||
InternalizeUtf8String(constant_string_table[i].contents);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
roots_[constant_string_table[i].index] = String::cast(obj);
|
||||
Handle<String> str =
|
||||
factory->InternalizeUtf8String(constant_string_table[i].contents);
|
||||
roots_[constant_string_table[i].index] = *str;
|
||||
}
|
||||
|
||||
Object* obj;
|
||||
|
||||
// Allocate the hidden string which is used to identify the hidden properties
|
||||
// in JSObjects. The hash code has a special value so that it will not match
|
||||
// the empty string when searching for the property. It cannot be part of the
|
||||
@ -2992,11 +2947,12 @@ bool Heap::CreateInitialObjects() {
|
||||
CreateFixedStubs();
|
||||
|
||||
// Allocate the dictionary of intrinsic function names.
|
||||
{ MaybeObject* maybe_obj =
|
||||
NameDictionary::Allocate(this, Runtime::kNumFunctions);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
{
|
||||
Handle<NameDictionary> function_names =
|
||||
NameDictionary::New(isolate(), Runtime::kNumFunctions);
|
||||
Runtime::InitializeIntrinsicFunctionNames(isolate(), function_names);
|
||||
set_intrinsic_function_names(*function_names);
|
||||
}
|
||||
set_intrinsic_function_names(NameDictionary::cast(obj));
|
||||
|
||||
{ MaybeObject* maybe_obj = AllocateInitialNumberStringCache();
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
@ -3195,60 +3151,58 @@ Object* RegExpResultsCache::Lookup(Heap* heap,
|
||||
}
|
||||
|
||||
|
||||
void RegExpResultsCache::Enter(Heap* heap,
|
||||
String* key_string,
|
||||
Object* key_pattern,
|
||||
FixedArray* value_array,
|
||||
void RegExpResultsCache::Enter(Isolate* isolate,
|
||||
Handle<String> key_string,
|
||||
Handle<Object> key_pattern,
|
||||
Handle<FixedArray> value_array,
|
||||
ResultsCacheType type) {
|
||||
FixedArray* cache;
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<FixedArray> cache;
|
||||
if (!key_string->IsInternalizedString()) return;
|
||||
if (type == STRING_SPLIT_SUBSTRINGS) {
|
||||
ASSERT(key_pattern->IsString());
|
||||
if (!key_pattern->IsInternalizedString()) return;
|
||||
cache = heap->string_split_cache();
|
||||
cache = factory->string_split_cache();
|
||||
} else {
|
||||
ASSERT(type == REGEXP_MULTIPLE_INDICES);
|
||||
ASSERT(key_pattern->IsFixedArray());
|
||||
cache = heap->regexp_multiple_cache();
|
||||
cache = factory->regexp_multiple_cache();
|
||||
}
|
||||
|
||||
uint32_t hash = key_string->Hash();
|
||||
uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
|
||||
~(kArrayEntriesPerCacheEntry - 1));
|
||||
if (cache->get(index + kStringOffset) == Smi::FromInt(0)) {
|
||||
cache->set(index + kStringOffset, key_string);
|
||||
cache->set(index + kPatternOffset, key_pattern);
|
||||
cache->set(index + kArrayOffset, value_array);
|
||||
cache->set(index + kStringOffset, *key_string);
|
||||
cache->set(index + kPatternOffset, *key_pattern);
|
||||
cache->set(index + kArrayOffset, *value_array);
|
||||
} else {
|
||||
uint32_t index2 =
|
||||
((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
|
||||
if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) {
|
||||
cache->set(index2 + kStringOffset, key_string);
|
||||
cache->set(index2 + kPatternOffset, key_pattern);
|
||||
cache->set(index2 + kArrayOffset, value_array);
|
||||
cache->set(index2 + kStringOffset, *key_string);
|
||||
cache->set(index2 + kPatternOffset, *key_pattern);
|
||||
cache->set(index2 + kArrayOffset, *value_array);
|
||||
} else {
|
||||
cache->set(index2 + kStringOffset, Smi::FromInt(0));
|
||||
cache->set(index2 + kPatternOffset, Smi::FromInt(0));
|
||||
cache->set(index2 + kArrayOffset, Smi::FromInt(0));
|
||||
cache->set(index + kStringOffset, key_string);
|
||||
cache->set(index + kPatternOffset, key_pattern);
|
||||
cache->set(index + kArrayOffset, value_array);
|
||||
cache->set(index + kStringOffset, *key_string);
|
||||
cache->set(index + kPatternOffset, *key_pattern);
|
||||
cache->set(index + kArrayOffset, *value_array);
|
||||
}
|
||||
}
|
||||
// If the array is a reasonably short list of substrings, convert it into a
|
||||
// list of internalized strings.
|
||||
if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) {
|
||||
for (int i = 0; i < value_array->length(); i++) {
|
||||
String* str = String::cast(value_array->get(i));
|
||||
Object* internalized_str;
|
||||
MaybeObject* maybe_string = heap->InternalizeString(str);
|
||||
if (maybe_string->ToObject(&internalized_str)) {
|
||||
value_array->set(i, internalized_str);
|
||||
}
|
||||
Handle<String> str(String::cast(value_array->get(i)), isolate);
|
||||
Handle<String> internalized_str = factory->InternalizeString(str);
|
||||
value_array->set(i, *internalized_str);
|
||||
}
|
||||
}
|
||||
// Convert backing store to a copy-on-write array.
|
||||
value_array->set_map_no_write_barrier(heap->fixed_cow_array_map());
|
||||
value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map());
|
||||
}
|
||||
|
||||
|
||||
@ -5972,16 +5926,12 @@ bool Heap::CreateHeapObjects() {
|
||||
|
||||
// Create initial objects
|
||||
if (!CreateInitialObjects()) return false;
|
||||
CHECK_EQ(0, gc_count_);
|
||||
|
||||
native_contexts_list_ = undefined_value();
|
||||
array_buffers_list_ = undefined_value();
|
||||
allocation_sites_list_ = undefined_value();
|
||||
weak_object_to_code_table_ = undefined_value();
|
||||
|
||||
HandleScope scope(isolate());
|
||||
Runtime::InitializeIntrinsicFunctionNames(
|
||||
isolate(), handle(intrinsic_function_names(), isolate()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
13
src/heap.h
13
src/heap.h
@ -2094,11 +2094,6 @@ class Heap {
|
||||
|
||||
void CreateFixedStubs();
|
||||
|
||||
MUST_USE_RESULT MaybeObject* CreateOddball(Map* map,
|
||||
const char* to_string,
|
||||
Object* to_number,
|
||||
byte kind);
|
||||
|
||||
// Allocate empty fixed array.
|
||||
MUST_USE_RESULT MaybeObject* AllocateEmptyFixedArray();
|
||||
|
||||
@ -2875,10 +2870,10 @@ class RegExpResultsCache {
|
||||
ResultsCacheType type);
|
||||
// Attempt to add value_array to the cache specified by type. On success,
|
||||
// value_array is turned into a COW-array.
|
||||
static void Enter(Heap* heap,
|
||||
String* key_string,
|
||||
Object* key_pattern,
|
||||
FixedArray* value_array,
|
||||
static void Enter(Isolate* isolate,
|
||||
Handle<String> key_string,
|
||||
Handle<Object> key_pattern,
|
||||
Handle<FixedArray> value_array,
|
||||
ResultsCacheType type);
|
||||
static void Clear(FixedArray* cache);
|
||||
static const int kRegExpResultsCacheSize = 0x100;
|
||||
|
@ -10096,20 +10096,16 @@ bool JSFunction::PassesFilter(const char* raw_filter) {
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Oddball::Initialize(Heap* heap,
|
||||
const char* to_string,
|
||||
Object* to_number,
|
||||
byte kind) {
|
||||
String* internalized_to_string;
|
||||
{ MaybeObject* maybe_string =
|
||||
heap->InternalizeUtf8String(
|
||||
CStrVector(to_string));
|
||||
if (!maybe_string->To(&internalized_to_string)) return maybe_string;
|
||||
}
|
||||
set_to_string(internalized_to_string);
|
||||
set_to_number(to_number);
|
||||
set_kind(kind);
|
||||
return this;
|
||||
void Oddball::Initialize(Isolate* isolate,
|
||||
Handle<Oddball> oddball,
|
||||
const char* to_string,
|
||||
Handle<Object> to_number,
|
||||
byte kind) {
|
||||
Handle<String> internalized_to_string =
|
||||
isolate->factory()->InternalizeUtf8String(CStrVector(to_string));
|
||||
oddball->set_to_string(*internalized_to_string);
|
||||
oddball->set_to_number(*to_number);
|
||||
oddball->set_kind(kind);
|
||||
}
|
||||
|
||||
|
||||
@ -14425,6 +14421,10 @@ Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
|
||||
int,
|
||||
JSObject::DeleteMode);
|
||||
|
||||
template Handle<NameDictionary>
|
||||
HashTable<NameDictionary, NameDictionaryShape, Name*>::
|
||||
New(Isolate*, int, MinimumCapacity, PretenureFlag);
|
||||
|
||||
template Handle<NameDictionary>
|
||||
HashTable<NameDictionary, NameDictionaryShape, Name*>::
|
||||
Shrink(Handle<NameDictionary>, Name* n);
|
||||
|
@ -9723,10 +9723,11 @@ class Oddball: public HeapObject {
|
||||
DECLARE_VERIFIER(Oddball)
|
||||
|
||||
// Initialize the fields.
|
||||
MUST_USE_RESULT MaybeObject* Initialize(Heap* heap,
|
||||
const char* to_string,
|
||||
Object* to_number,
|
||||
byte kind);
|
||||
static void Initialize(Isolate* isolate,
|
||||
Handle<Oddball> oddball,
|
||||
const char* to_string,
|
||||
Handle<Object> to_number,
|
||||
byte kind);
|
||||
|
||||
// Layout description.
|
||||
static const int kToStringOffset = HeapObject::kHeaderSize;
|
||||
|
@ -4730,10 +4730,10 @@ static MaybeObject* SearchRegExpMultiple(
|
||||
fixed_array->set(fixed_array->length() - 1,
|
||||
Smi::FromInt(builder.length()));
|
||||
// Cache the result and turn the FixedArray into a COW array.
|
||||
RegExpResultsCache::Enter(isolate->heap(),
|
||||
*subject,
|
||||
regexp->data(),
|
||||
*fixed_array,
|
||||
RegExpResultsCache::Enter(isolate,
|
||||
subject,
|
||||
handle(regexp->data(), isolate),
|
||||
fixed_array,
|
||||
RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
|
||||
}
|
||||
return *builder.ToJSArray(result_array);
|
||||
@ -6750,10 +6750,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
|
||||
|
||||
if (limit == 0xffffffffu) {
|
||||
if (result->HasFastObjectElements()) {
|
||||
RegExpResultsCache::Enter(isolate->heap(),
|
||||
*subject,
|
||||
*pattern,
|
||||
*elements,
|
||||
RegExpResultsCache::Enter(isolate,
|
||||
subject,
|
||||
pattern,
|
||||
elements,
|
||||
RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user