* Move almost all roots into an array ready for use by a constant-pool

register on ARM.
* Make some compile-time loops into run-time loops for compactness.
Review URL: http://codereview.chromium.org/149324

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2398 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2009-07-08 19:12:58 +00:00
parent bf656d2ae1
commit 8f73ae0325
11 changed files with 484 additions and 319 deletions

View File

@ -85,7 +85,7 @@ Handle<Code> CodeStub::GetCode() {
Handle<NumberDictionary>(Heap::code_stubs()),
key,
code);
Heap::set_code_stubs(*dict);
Heap::public_set_code_stubs(*dict);
index = Heap::code_stubs()->FindEntry(key);
}
ASSERT(index != NumberDictionary::kNotFound);

View File

@ -28,6 +28,7 @@
#ifndef V8_FACTORY_H_
#define V8_FACTORY_H_
#include "globals.h"
#include "heap.h"
#include "zone-inl.h"
@ -299,13 +300,19 @@ class Factory : public AllStatic {
Handle<JSObject> instance,
bool* pending_exception);
#define ROOT_ACCESSOR(type, name) \
static Handle<type> name() { return Handle<type>(&Heap::name##_); }
#define ROOT_ACCESSOR(type, name, camel_name) \
static inline Handle<type> name() { \
return Handle<type>(bit_cast<type**, Object**>( \
&Heap::roots_[Heap::k##camel_name##RootIndex])); \
}
ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR_ACCESSOR
#define SYMBOL_ACCESSOR(name, str) \
static Handle<String> name() { return Handle<String>(&Heap::name##_); }
static inline Handle<String> name() { \
return Handle<String>(bit_cast<String**, Object**>( \
&Heap::roots_[Heap::k##name##RootIndex])); \
}
SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR

View File

@ -216,7 +216,7 @@ void Heap::ScavengeObject(HeapObject** p, HeapObject* object) {
void Heap::SetLastScriptId(Object* last_script_id) {
last_script_id_ = last_script_id;
roots_[kLastScriptIdRootIndex] = last_script_id;
}

View File

@ -43,21 +43,10 @@
namespace v8 {
namespace internal {
#define ROOT_ALLOCATION(type, name) type* Heap::name##_;
ROOT_LIST(ROOT_ALLOCATION)
#undef ROOT_ALLOCATION
#define STRUCT_ALLOCATION(NAME, Name, name) Map* Heap::name##_map_;
STRUCT_LIST(STRUCT_ALLOCATION)
#undef STRUCT_ALLOCATION
#define SYMBOL_ALLOCATION(name, string) String* Heap::name##_;
SYMBOL_LIST(SYMBOL_ALLOCATION)
#undef SYMBOL_ALLOCATION
String* Heap::hidden_symbol_;
Object* Heap::roots_[Heap::kRootListLength];
NewSpace Heap::new_space_;
OldSpace* Heap::old_pointer_space_ = NULL;
@ -284,9 +273,8 @@ void Heap::GarbageCollectionEpilogue() {
Counters::alive_after_last_gc.Set(SizeOfObjects());
SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table_);
Counters::symbol_table_capacity.Set(symbol_table->Capacity());
Counters::number_of_symbols.Set(symbol_table->NumberOfElements());
Counters::symbol_table_capacity.Set(symbol_table()->Capacity());
Counters::number_of_symbols.Set(symbol_table()->NumberOfElements());
#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
ReportStatisticsAfterGC();
#endif
@ -405,8 +393,7 @@ class SymbolTableVerifier : public ObjectVisitor {
static void VerifySymbolTable() {
#ifdef DEBUG
SymbolTableVerifier verifier;
SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table());
symbol_table->IterateElements(&verifier);
Heap::symbol_table()->IterateElements(&verifier);
#endif // DEBUG
}
@ -1012,7 +999,7 @@ Object* Heap::AllocatePartialMap(InstanceType instance_type,
if (result->IsFailure()) return result;
// Map::cast cannot be used due to uninitialized map field.
reinterpret_cast<Map*>(result)->set_map(meta_map());
reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map());
reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
reinterpret_cast<Map*>(result)->set_inobject_properties(0);
@ -1041,41 +1028,66 @@ Object* Heap::AllocateMap(InstanceType instance_type, int instance_size) {
}
const Heap::StringTypeTable Heap::string_type_table[] = {
#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
{type, size, k##camel_name##MapRootIndex},
STRING_TYPE_LIST(STRING_TYPE_ELEMENT)
#undef STRING_TYPE_ELEMENT
};
const Heap::ConstantSymbolTable Heap::constant_symbol_table[] = {
#define CONSTANT_SYMBOL_ELEMENT(name, contents) \
{contents, k##name##RootIndex},
SYMBOL_LIST(CONSTANT_SYMBOL_ELEMENT)
#undef CONSTANT_SYMBOL_ELEMENT
};
const Heap::StructTable Heap::struct_table[] = {
#define STRUCT_TABLE_ELEMENT(NAME, Name, name) \
{ NAME##_TYPE, Name::kSize, k##Name##MapRootIndex },
STRUCT_LIST(STRUCT_TABLE_ELEMENT)
#undef STRUCT_TABLE_ELEMENT
};
bool Heap::CreateInitialMaps() {
Object* obj = AllocatePartialMap(MAP_TYPE, Map::kSize);
if (obj->IsFailure()) return false;
// Map::cast cannot be used due to uninitialized map field.
meta_map_ = reinterpret_cast<Map*>(obj);
meta_map()->set_map(meta_map());
Map* new_meta_map = reinterpret_cast<Map*>(obj);
set_meta_map(new_meta_map);
new_meta_map->set_map(new_meta_map);
obj = AllocatePartialMap(FIXED_ARRAY_TYPE, FixedArray::kHeaderSize);
if (obj->IsFailure()) return false;
fixed_array_map_ = Map::cast(obj);
set_fixed_array_map(Map::cast(obj));
obj = AllocatePartialMap(ODDBALL_TYPE, Oddball::kSize);
if (obj->IsFailure()) return false;
oddball_map_ = Map::cast(obj);
set_oddball_map(Map::cast(obj));
obj = AllocatePartialMap(JS_GLOBAL_PROPERTY_CELL_TYPE,
JSGlobalPropertyCell::kSize);
if (obj->IsFailure()) return false;
global_property_cell_map_ = Map::cast(obj);
set_global_property_cell_map(Map::cast(obj));
// Allocate the empty array
obj = AllocateEmptyFixedArray();
if (obj->IsFailure()) return false;
empty_fixed_array_ = FixedArray::cast(obj);
set_empty_fixed_array(FixedArray::cast(obj));
obj = Allocate(oddball_map(), OLD_DATA_SPACE);
if (obj->IsFailure()) return false;
null_value_ = obj;
set_null_value(obj);
// Allocate the empty descriptor array. AllocateMap can now be used.
obj = AllocateEmptyFixedArray();
if (obj->IsFailure()) return false;
// There is a check against empty_descriptor_array() in cast().
empty_descriptor_array_ = reinterpret_cast<DescriptorArray*>(obj);
set_empty_descriptor_array(reinterpret_cast<DescriptorArray*>(obj));
// Fix the instance_descriptors for the existing maps.
meta_map()->set_instance_descriptors(empty_descriptor_array());
@ -1105,95 +1117,95 @@ bool Heap::CreateInitialMaps() {
obj = AllocateMap(HEAP_NUMBER_TYPE, HeapNumber::kSize);
if (obj->IsFailure()) return false;
heap_number_map_ = Map::cast(obj);
set_heap_number_map(Map::cast(obj));
obj = AllocateMap(PROXY_TYPE, Proxy::kSize);
if (obj->IsFailure()) return false;
proxy_map_ = Map::cast(obj);
set_proxy_map(Map::cast(obj));
#define ALLOCATE_STRING_MAP(type, size, name) \
obj = AllocateMap(type, size); \
if (obj->IsFailure()) return false; \
name##_map_ = Map::cast(obj);
STRING_TYPE_LIST(ALLOCATE_STRING_MAP);
#undef ALLOCATE_STRING_MAP
for (unsigned i = 0; i < ARRAY_SIZE(string_type_table); i++) {
const StringTypeTable& entry = string_type_table[i];
obj = AllocateMap(entry.type, entry.size);
if (obj->IsFailure()) return false;
roots_[entry.index] = Map::cast(obj);
}
obj = AllocateMap(SHORT_STRING_TYPE, SeqTwoByteString::kAlignedSize);
if (obj->IsFailure()) return false;
undetectable_short_string_map_ = Map::cast(obj);
undetectable_short_string_map_->set_is_undetectable();
set_undetectable_short_string_map(Map::cast(obj));
Map::cast(obj)->set_is_undetectable();
obj = AllocateMap(MEDIUM_STRING_TYPE, SeqTwoByteString::kAlignedSize);
if (obj->IsFailure()) return false;
undetectable_medium_string_map_ = Map::cast(obj);
undetectable_medium_string_map_->set_is_undetectable();
set_undetectable_medium_string_map(Map::cast(obj));
Map::cast(obj)->set_is_undetectable();
obj = AllocateMap(LONG_STRING_TYPE, SeqTwoByteString::kAlignedSize);
if (obj->IsFailure()) return false;
undetectable_long_string_map_ = Map::cast(obj);
undetectable_long_string_map_->set_is_undetectable();
set_undetectable_long_string_map(Map::cast(obj));
Map::cast(obj)->set_is_undetectable();
obj = AllocateMap(SHORT_ASCII_STRING_TYPE, SeqAsciiString::kAlignedSize);
if (obj->IsFailure()) return false;
undetectable_short_ascii_string_map_ = Map::cast(obj);
undetectable_short_ascii_string_map_->set_is_undetectable();
set_undetectable_short_ascii_string_map(Map::cast(obj));
Map::cast(obj)->set_is_undetectable();
obj = AllocateMap(MEDIUM_ASCII_STRING_TYPE, SeqAsciiString::kAlignedSize);
if (obj->IsFailure()) return false;
undetectable_medium_ascii_string_map_ = Map::cast(obj);
undetectable_medium_ascii_string_map_->set_is_undetectable();
set_undetectable_medium_ascii_string_map(Map::cast(obj));
Map::cast(obj)->set_is_undetectable();
obj = AllocateMap(LONG_ASCII_STRING_TYPE, SeqAsciiString::kAlignedSize);
if (obj->IsFailure()) return false;
undetectable_long_ascii_string_map_ = Map::cast(obj);
undetectable_long_ascii_string_map_->set_is_undetectable();
set_undetectable_long_ascii_string_map(Map::cast(obj));
Map::cast(obj)->set_is_undetectable();
obj = AllocateMap(BYTE_ARRAY_TYPE, Array::kAlignedSize);
if (obj->IsFailure()) return false;
byte_array_map_ = Map::cast(obj);
set_byte_array_map(Map::cast(obj));
obj = AllocateMap(CODE_TYPE, Code::kHeaderSize);
if (obj->IsFailure()) return false;
code_map_ = Map::cast(obj);
set_code_map(Map::cast(obj));
obj = AllocateMap(FILLER_TYPE, kPointerSize);
if (obj->IsFailure()) return false;
one_word_filler_map_ = Map::cast(obj);
set_one_word_filler_map(Map::cast(obj));
obj = AllocateMap(FILLER_TYPE, 2 * kPointerSize);
if (obj->IsFailure()) return false;
two_word_filler_map_ = Map::cast(obj);
set_two_word_filler_map(Map::cast(obj));
#define ALLOCATE_STRUCT_MAP(NAME, Name, name) \
obj = AllocateMap(NAME##_TYPE, Name::kSize); \
if (obj->IsFailure()) return false; \
name##_map_ = Map::cast(obj);
STRUCT_LIST(ALLOCATE_STRUCT_MAP)
#undef ALLOCATE_STRUCT_MAP
for (unsigned i = 0; i < ARRAY_SIZE(struct_table); i++) {
const StructTable& entry = struct_table[i];
obj = AllocateMap(entry.type, entry.size);
if (obj->IsFailure()) return false;
roots_[entry.index] = Map::cast(obj);
}
obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize);
if (obj->IsFailure()) return false;
hash_table_map_ = Map::cast(obj);
set_hash_table_map(Map::cast(obj));
obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize);
if (obj->IsFailure()) return false;
context_map_ = Map::cast(obj);
set_context_map(Map::cast(obj));
obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize);
if (obj->IsFailure()) return false;
catch_context_map_ = Map::cast(obj);
set_catch_context_map(Map::cast(obj));
obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize);
if (obj->IsFailure()) return false;
global_context_map_ = Map::cast(obj);
set_global_context_map(Map::cast(obj));
obj = AllocateMap(JS_FUNCTION_TYPE, JSFunction::kSize);
if (obj->IsFailure()) return false;
boilerplate_function_map_ = Map::cast(obj);
set_boilerplate_function_map(Map::cast(obj));
obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kSize);
if (obj->IsFailure()) return false;
shared_function_info_map_ = Map::cast(obj);
set_shared_function_info_map(Map::cast(obj));
ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
return true;
@ -1254,15 +1266,15 @@ bool Heap::CreateApiObjects() {
obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
if (obj->IsFailure()) return false;
neander_map_ = Map::cast(obj);
set_neander_map(Map::cast(obj));
obj = Heap::AllocateJSObjectFromMap(neander_map_);
obj = Heap::AllocateJSObjectFromMap(neander_map());
if (obj->IsFailure()) return false;
Object* elements = AllocateFixedArray(2);
if (elements->IsFailure()) return false;
FixedArray::cast(elements)->set(0, Smi::FromInt(0));
JSObject::cast(obj)->set_elements(FixedArray::cast(elements));
message_listeners_ = JSObject::cast(obj);
set_message_listeners(JSObject::cast(obj));
return true;
}
@ -1270,25 +1282,25 @@ bool Heap::CreateApiObjects() {
void Heap::CreateCEntryStub() {
CEntryStub stub;
c_entry_code_ = *stub.GetCode();
set_c_entry_code(*stub.GetCode());
}
void Heap::CreateCEntryDebugBreakStub() {
CEntryDebugBreakStub stub;
c_entry_debug_break_code_ = *stub.GetCode();
set_c_entry_debug_break_code(*stub.GetCode());
}
void Heap::CreateJSEntryStub() {
JSEntryStub stub;
js_entry_code_ = *stub.GetCode();
set_js_entry_code(*stub.GetCode());
}
void Heap::CreateJSConstructEntryStub() {
JSConstructEntryStub stub;
js_construct_entry_code_ = *stub.GetCode();
set_js_construct_entry_code(*stub.GetCode());
}
@ -1319,34 +1331,35 @@ bool Heap::CreateInitialObjects() {
// The -0 value must be set before NumberFromDouble works.
obj = AllocateHeapNumber(-0.0, TENURED);
if (obj->IsFailure()) return false;
minus_zero_value_ = obj;
ASSERT(signbit(minus_zero_value_->Number()) != 0);
set_minus_zero_value(obj);
ASSERT(signbit(minus_zero_value()->Number()) != 0);
obj = AllocateHeapNumber(OS::nan_value(), TENURED);
if (obj->IsFailure()) return false;
nan_value_ = obj;
set_nan_value(obj);
obj = Allocate(oddball_map(), OLD_DATA_SPACE);
if (obj->IsFailure()) return false;
undefined_value_ = obj;
set_undefined_value(obj);
ASSERT(!InNewSpace(undefined_value()));
// Allocate initial symbol table.
obj = SymbolTable::Allocate(kInitialSymbolTableSize);
if (obj->IsFailure()) return false;
symbol_table_ = obj;
// Don't use set_symbol_table() due to asserts.
roots_[kSymbolTableRootIndex] = obj;
// Assign the print strings for oddballs after creating symboltable.
Object* symbol = LookupAsciiSymbol("undefined");
if (symbol->IsFailure()) return false;
Oddball::cast(undefined_value_)->set_to_string(String::cast(symbol));
Oddball::cast(undefined_value_)->set_to_number(nan_value_);
Oddball::cast(undefined_value())->set_to_string(String::cast(symbol));
Oddball::cast(undefined_value())->set_to_number(nan_value());
// Assign the print strings for oddballs after creating symboltable.
symbol = LookupAsciiSymbol("null");
if (symbol->IsFailure()) return false;
Oddball::cast(null_value_)->set_to_string(String::cast(symbol));
Oddball::cast(null_value_)->set_to_number(Smi::FromInt(0));
Oddball::cast(null_value())->set_to_string(String::cast(symbol));
Oddball::cast(null_value())->set_to_number(Smi::FromInt(0));
// Allocate the null_value
obj = Oddball::cast(null_value())->Initialize("null", Smi::FromInt(0));
@ -1354,32 +1367,31 @@ bool Heap::CreateInitialObjects() {
obj = CreateOddball(oddball_map(), "true", Smi::FromInt(1));
if (obj->IsFailure()) return false;
true_value_ = obj;
set_true_value(obj);
obj = CreateOddball(oddball_map(), "false", Smi::FromInt(0));
if (obj->IsFailure()) return false;
false_value_ = obj;
set_false_value(obj);
obj = CreateOddball(oddball_map(), "hole", Smi::FromInt(-1));
if (obj->IsFailure()) return false;
the_hole_value_ = obj;
set_the_hole_value(obj);
// Allocate the empty string.
obj = AllocateRawAsciiString(0, TENURED);
if (obj->IsFailure()) return false;
empty_string_ = String::cast(obj);
set_empty_string(String::cast(obj));
#define SYMBOL_INITIALIZE(name, string) \
obj = LookupAsciiSymbol(string); \
if (obj->IsFailure()) return false; \
(name##_) = String::cast(obj);
SYMBOL_LIST(SYMBOL_INITIALIZE)
#undef SYMBOL_INITIALIZE
for (unsigned i = 0; i < ARRAY_SIZE(constant_symbol_table); i++) {
obj = LookupAsciiSymbol(constant_symbol_table[i].contents);
if (obj->IsFailure()) return false;
roots_[constant_symbol_table[i].index] = String::cast(obj);
}
// Allocate the hidden symbol 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
// SYMBOL_LIST because it needs to be allocated manually with the special
// loop above because it needs to be allocated manually with the special
// hash code in place. The hash code for the hidden_symbol is zero to ensure
// that it will always be at the first entry in property descriptors.
obj = AllocateSymbol(CStrVector(""), 0, String::kHashComputedMask);
@ -1389,37 +1401,37 @@ bool Heap::CreateInitialObjects() {
// Allocate the proxy for __proto__.
obj = AllocateProxy((Address) &Accessors::ObjectPrototype);
if (obj->IsFailure()) return false;
prototype_accessors_ = Proxy::cast(obj);
set_prototype_accessors(Proxy::cast(obj));
// Allocate the code_stubs dictionary.
obj = NumberDictionary::Allocate(4);
if (obj->IsFailure()) return false;
code_stubs_ = NumberDictionary::cast(obj);
set_code_stubs(NumberDictionary::cast(obj));
// Allocate the non_monomorphic_cache used in stub-cache.cc
obj = NumberDictionary::Allocate(4);
if (obj->IsFailure()) return false;
non_monomorphic_cache_ = NumberDictionary::cast(obj);
set_non_monomorphic_cache(NumberDictionary::cast(obj));
CreateFixedStubs();
// Allocate the number->string conversion cache
obj = AllocateFixedArray(kNumberStringCacheSize * 2);
if (obj->IsFailure()) return false;
number_string_cache_ = FixedArray::cast(obj);
set_number_string_cache(FixedArray::cast(obj));
// Allocate cache for single character strings.
obj = AllocateFixedArray(String::kMaxAsciiCharCode+1);
if (obj->IsFailure()) return false;
single_character_string_cache_ = FixedArray::cast(obj);
set_single_character_string_cache(FixedArray::cast(obj));
// Allocate cache for external strings pointing to native source code.
obj = AllocateFixedArray(Natives::GetBuiltinsCount());
if (obj->IsFailure()) return false;
natives_source_cache_ = FixedArray::cast(obj);
set_natives_source_cache(FixedArray::cast(obj));
// Handling of script id generation is in Factory::NewScript.
last_script_id_ = undefined_value();
set_last_script_id(undefined_value());
// Initialize keyed lookup cache.
KeyedLookupCache::Clear();
@ -1457,13 +1469,13 @@ Object* Heap::GetNumberStringCache(Object* number) {
} else {
hash = double_get_hash(number->Number());
}
Object* key = number_string_cache_->get(hash * 2);
Object* key = number_string_cache()->get(hash * 2);
if (key == number) {
return String::cast(number_string_cache_->get(hash * 2 + 1));
return String::cast(number_string_cache()->get(hash * 2 + 1));
} else if (key->IsHeapNumber() &&
number->IsHeapNumber() &&
key->Number() == number->Number()) {
return String::cast(number_string_cache_->get(hash * 2 + 1));
return String::cast(number_string_cache()->get(hash * 2 + 1));
}
return undefined_value();
}
@ -1473,12 +1485,12 @@ void Heap::SetNumberStringCache(Object* number, String* string) {
int hash;
if (number->IsSmi()) {
hash = smi_get_hash(Smi::cast(number));
number_string_cache_->set(hash * 2, number, SKIP_WRITE_BARRIER);
number_string_cache()->set(hash * 2, number, SKIP_WRITE_BARRIER);
} else {
hash = double_get_hash(number->Number());
number_string_cache_->set(hash * 2, number);
number_string_cache()->set(hash * 2, number);
}
number_string_cache_->set(hash * 2 + 1, string);
number_string_cache()->set(hash * 2 + 1, string);
}
@ -1491,19 +1503,19 @@ Object* Heap::SmiOrNumberFromDouble(double value,
static const DoubleRepresentation plus_zero(0.0);
static const DoubleRepresentation minus_zero(-0.0);
static const DoubleRepresentation nan(OS::nan_value());
ASSERT(minus_zero_value_ != NULL);
ASSERT(minus_zero_value() != NULL);
ASSERT(sizeof(plus_zero.value) == sizeof(plus_zero.bits));
DoubleRepresentation rep(value);
if (rep.bits == plus_zero.bits) return Smi::FromInt(0); // not uncommon
if (rep.bits == minus_zero.bits) {
return new_object ? AllocateHeapNumber(-0.0, pretenure)
: minus_zero_value_;
: minus_zero_value();
}
if (rep.bits == nan.bits) {
return new_object
? AllocateHeapNumber(OS::nan_value(), pretenure)
: nan_value_;
: nan_value();
}
// Try to represent the value as a tagged small integer.
@ -2754,10 +2766,11 @@ void Heap::Verify() {
Object* Heap::LookupSymbol(Vector<const char> string) {
Object* symbol = NULL;
Object* new_table =
SymbolTable::cast(symbol_table_)->LookupSymbol(string, &symbol);
Object* new_table = symbol_table()->LookupSymbol(string, &symbol);
if (new_table->IsFailure()) return new_table;
symbol_table_ = new_table;
// Can't use set_symbol_table because SymbolTable::cast knows that
// SymbolTable is a singleton and checks for identity.
roots_[kSymbolTableRootIndex] = new_table;
ASSERT(symbol != NULL);
return symbol;
}
@ -2766,10 +2779,11 @@ Object* Heap::LookupSymbol(Vector<const char> string) {
Object* Heap::LookupSymbol(String* string) {
if (string->IsSymbol()) return string;
Object* symbol = NULL;
Object* new_table =
SymbolTable::cast(symbol_table_)->LookupString(string, &symbol);
Object* new_table = symbol_table()->LookupString(string, &symbol);
if (new_table->IsFailure()) return new_table;
symbol_table_ = new_table;
// Can't use set_symbol_table because SymbolTable::cast knows that
// SymbolTable is a singleton and checks for identity.
roots_[kSymbolTableRootIndex] = new_table;
ASSERT(symbol != NULL);
return symbol;
}
@ -2780,8 +2794,7 @@ bool Heap::LookupSymbolIfExists(String* string, String** symbol) {
*symbol = string;
return true;
}
SymbolTable* table = SymbolTable::cast(symbol_table_);
return table->LookupSymbolIfExists(string, symbol);
return symbol_table()->LookupSymbolIfExists(string, symbol);
}
@ -2868,28 +2881,15 @@ void Heap::IterateRSet(PagedSpace* space, ObjectSlotCallback copy_object_func) {
void Heap::IterateRoots(ObjectVisitor* v) {
IterateStrongRoots(v);
v->VisitPointer(reinterpret_cast<Object**>(&symbol_table_));
v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex]));
SYNCHRONIZE_TAG("symbol_table");
}
void Heap::IterateStrongRoots(ObjectVisitor* v) {
#define ROOT_ITERATE(type, name) \
v->VisitPointer(bit_cast<Object**, type**>(&name##_));
STRONG_ROOT_LIST(ROOT_ITERATE);
#undef ROOT_ITERATE
v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
SYNCHRONIZE_TAG("strong_root_list");
#define STRUCT_MAP_ITERATE(NAME, Name, name) \
v->VisitPointer(bit_cast<Object**, Map**>(&name##_map_));
STRUCT_LIST(STRUCT_MAP_ITERATE);
#undef STRUCT_MAP_ITERATE
SYNCHRONIZE_TAG("struct_map");
#define SYMBOL_ITERATE(name, string) \
v->VisitPointer(bit_cast<Object**, String**>(&name##_));
SYMBOL_LIST(SYMBOL_ITERATE)
#undef SYMBOL_ITERATE
v->VisitPointer(bit_cast<Object**, String**>(&hidden_symbol_));
SYNCHRONIZE_TAG("symbol");
@ -3366,8 +3366,8 @@ void HeapProfiler::WriteSample() {
// Lump all the string types together.
int string_number = 0;
int string_bytes = 0;
#define INCREMENT_SIZE(type, size, name) \
string_number += info[type].number(); \
#define INCREMENT_SIZE(type, size, name, camel_name) \
string_number += info[type].number(); \
string_bytes += info[type].bytes();
STRING_TYPE_LIST(INCREMENT_SIZE)
#undef INCREMENT_SIZE

View File

@ -34,105 +34,107 @@ namespace v8 {
namespace internal {
// Defines all the roots in Heap.
#define STRONG_ROOT_LIST(V) \
V(Map, meta_map) \
V(Map, heap_number_map) \
V(Map, short_string_map) \
V(Map, medium_string_map) \
V(Map, long_string_map) \
V(Map, short_ascii_string_map) \
V(Map, medium_ascii_string_map) \
V(Map, long_ascii_string_map) \
V(Map, short_symbol_map) \
V(Map, medium_symbol_map) \
V(Map, long_symbol_map) \
V(Map, short_ascii_symbol_map) \
V(Map, medium_ascii_symbol_map) \
V(Map, long_ascii_symbol_map) \
V(Map, short_cons_symbol_map) \
V(Map, medium_cons_symbol_map) \
V(Map, long_cons_symbol_map) \
V(Map, short_cons_ascii_symbol_map) \
V(Map, medium_cons_ascii_symbol_map) \
V(Map, long_cons_ascii_symbol_map) \
V(Map, short_sliced_symbol_map) \
V(Map, medium_sliced_symbol_map) \
V(Map, long_sliced_symbol_map) \
V(Map, short_sliced_ascii_symbol_map) \
V(Map, medium_sliced_ascii_symbol_map) \
V(Map, long_sliced_ascii_symbol_map) \
V(Map, short_external_symbol_map) \
V(Map, medium_external_symbol_map) \
V(Map, long_external_symbol_map) \
V(Map, short_external_ascii_symbol_map) \
V(Map, medium_external_ascii_symbol_map) \
V(Map, long_external_ascii_symbol_map) \
V(Map, short_cons_string_map) \
V(Map, medium_cons_string_map) \
V(Map, long_cons_string_map) \
V(Map, short_cons_ascii_string_map) \
V(Map, medium_cons_ascii_string_map) \
V(Map, long_cons_ascii_string_map) \
V(Map, short_sliced_string_map) \
V(Map, medium_sliced_string_map) \
V(Map, long_sliced_string_map) \
V(Map, short_sliced_ascii_string_map) \
V(Map, medium_sliced_ascii_string_map) \
V(Map, long_sliced_ascii_string_map) \
V(Map, short_external_string_map) \
V(Map, medium_external_string_map) \
V(Map, long_external_string_map) \
V(Map, short_external_ascii_string_map) \
V(Map, medium_external_ascii_string_map) \
V(Map, long_external_ascii_string_map) \
V(Map, undetectable_short_string_map) \
V(Map, undetectable_medium_string_map) \
V(Map, undetectable_long_string_map) \
V(Map, undetectable_short_ascii_string_map) \
V(Map, undetectable_medium_ascii_string_map) \
V(Map, undetectable_long_ascii_string_map) \
V(Map, byte_array_map) \
V(Map, fixed_array_map) \
V(Map, hash_table_map) \
V(Map, context_map) \
V(Map, catch_context_map) \
V(Map, global_context_map) \
V(Map, code_map) \
V(Map, oddball_map) \
V(Map, global_property_cell_map) \
V(Map, boilerplate_function_map) \
V(Map, shared_function_info_map) \
V(Map, proxy_map) \
V(Map, one_word_filler_map) \
V(Map, two_word_filler_map) \
V(Object, nan_value) \
V(Object, undefined_value) \
V(Object, minus_zero_value) \
V(Object, null_value) \
V(Object, true_value) \
V(Object, false_value) \
V(String, empty_string) \
V(FixedArray, empty_fixed_array) \
V(DescriptorArray, empty_descriptor_array) \
V(Object, the_hole_value) \
V(Map, neander_map) \
V(JSObject, message_listeners) \
V(Proxy, prototype_accessors) \
V(NumberDictionary, code_stubs) \
V(NumberDictionary, non_monomorphic_cache) \
V(Code, js_entry_code) \
V(Code, js_construct_entry_code) \
V(Code, c_entry_code) \
V(Code, c_entry_debug_break_code) \
V(FixedArray, number_string_cache) \
V(FixedArray, single_character_string_cache) \
V(FixedArray, natives_source_cache) \
V(Object, last_script_id)
#define STRONG_ROOT_LIST(V) \
V(Map, meta_map, MetaMap) \
V(Map, heap_number_map, HeapNumberMap) \
V(Map, short_string_map, ShortStringMap) \
V(Map, medium_string_map, MediumStringMap) \
V(Map, long_string_map, LongStringMap) \
V(Map, short_ascii_string_map, ShortAsciiStringMap) \
V(Map, medium_ascii_string_map, MediumAsciiStringMap) \
V(Map, long_ascii_string_map, LongAsciiStringMap) \
V(Map, short_symbol_map, ShortSymbolMap) \
V(Map, medium_symbol_map, MediumSymbolMap) \
V(Map, long_symbol_map, LongSymbolMap) \
V(Map, short_ascii_symbol_map, ShortAsciiSymbolMap) \
V(Map, medium_ascii_symbol_map, MediumAsciiSymbolMap) \
V(Map, long_ascii_symbol_map, LongAsciiSymbolMap) \
V(Map, short_cons_symbol_map, ShortConsSymbolMap) \
V(Map, medium_cons_symbol_map, MediumConsSymbolMap) \
V(Map, long_cons_symbol_map, LongConsSymbolMap) \
V(Map, short_cons_ascii_symbol_map, ShortConsAsciiSymbolMap) \
V(Map, medium_cons_ascii_symbol_map, MediumConsAsciiSymbolMap) \
V(Map, long_cons_ascii_symbol_map, LongConsAsciiSymbolMap) \
V(Map, short_sliced_symbol_map, ShortSlicedSymbolMap) \
V(Map, medium_sliced_symbol_map, MediumSlicedSymbolMap) \
V(Map, long_sliced_symbol_map, LongSlicedSymbolMap) \
V(Map, short_sliced_ascii_symbol_map, ShortSlicedAsciiSymbolMap) \
V(Map, medium_sliced_ascii_symbol_map, MediumSlicedAsciiSymbolMap) \
V(Map, long_sliced_ascii_symbol_map, LongSlicedAsciiSymbolMap) \
V(Map, short_external_symbol_map, ShortExternalSymbolMap) \
V(Map, medium_external_symbol_map, MediumExternalSymbolMap) \
V(Map, long_external_symbol_map, LongExternalSymbolMap) \
V(Map, short_external_ascii_symbol_map, ShortExternalAsciiSymbolMap) \
V(Map, medium_external_ascii_symbol_map, MediumExternalAsciiSymbolMap) \
V(Map, long_external_ascii_symbol_map, LongExternalAsciiSymbolMap) \
V(Map, short_cons_string_map, ShortConsStringMap) \
V(Map, medium_cons_string_map, MediumConsStringMap) \
V(Map, long_cons_string_map, LongConsStringMap) \
V(Map, short_cons_ascii_string_map, ShortConsAsciiStringMap) \
V(Map, medium_cons_ascii_string_map, MediumConsAsciiStringMap) \
V(Map, long_cons_ascii_string_map, LongConsAsciiStringMap) \
V(Map, short_sliced_string_map, ShortSlicedStringMap) \
V(Map, medium_sliced_string_map, MediumSlicedStringMap) \
V(Map, long_sliced_string_map, LongSlicedStringMap) \
V(Map, short_sliced_ascii_string_map, ShortSlicedAsciiStringMap) \
V(Map, medium_sliced_ascii_string_map, MediumSlicedAsciiStringMap) \
V(Map, long_sliced_ascii_string_map, LongSlicedAsciiStringMap) \
V(Map, short_external_string_map, ShortExternalStringMap) \
V(Map, medium_external_string_map, MediumExternalStringMap) \
V(Map, long_external_string_map, LongExternalStringMap) \
V(Map, short_external_ascii_string_map, ShortExternalAsciiStringMap) \
V(Map, medium_external_ascii_string_map, MediumExternalAsciiStringMap) \
V(Map, long_external_ascii_string_map, LongExternalAsciiStringMap) \
V(Map, undetectable_short_string_map, UndetectableShortStringMap) \
V(Map, undetectable_medium_string_map, UndetectableMediumStringMap) \
V(Map, undetectable_long_string_map, UndetectableLongStringMap) \
V(Map, undetectable_short_ascii_string_map, UndetectableShortAsciiStringMap) \
V(Map, \
undetectable_medium_ascii_string_map, \
UndetectableMediumAsciiStringMap) \
V(Map, undetectable_long_ascii_string_map, UndetectableLongAsciiStringMap) \
V(Map, byte_array_map, ByteArrayMap) \
V(Map, fixed_array_map, FixedArrayMap) \
V(Map, hash_table_map, HashTableMap) \
V(Map, context_map, ContextMap) \
V(Map, catch_context_map, CatchContextMap) \
V(Map, global_context_map, GlobalContextMap) \
V(Map, code_map, CodeMap) \
V(Map, oddball_map, OddballMap) \
V(Map, global_property_cell_map, GlobalPropertyCellMap) \
V(Map, boilerplate_function_map, BoilerplateFunctionMap) \
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
V(Map, proxy_map, ProxyMap) \
V(Map, one_word_filler_map, OneWordFillerMap) \
V(Map, two_word_filler_map, TwoWordFillerMap) \
V(Object, nan_value, NanValue) \
V(Object, undefined_value, UndefinedValue) \
V(Object, minus_zero_value, MinusZeroValue) \
V(Object, null_value, NullValue) \
V(Object, true_value, TrueValue) \
V(Object, false_value, FalseValue) \
V(String, empty_string, EmptyString) \
V(FixedArray, empty_fixed_array, EmptyFixedArray) \
V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \
V(Object, the_hole_value, TheHoleValue) \
V(Map, neander_map, NeanderMap) \
V(JSObject, message_listeners, MessageListeners) \
V(Proxy, prototype_accessors, PrototypeAccessors) \
V(NumberDictionary, code_stubs, CodeStubs) \
V(NumberDictionary, non_monomorphic_cache, NonMonomorphicCache) \
V(Code, js_entry_code, JsEntryCode) \
V(Code, js_construct_entry_code, JsConstructEntryCode) \
V(Code, c_entry_code, CEntryCode) \
V(Code, c_entry_debug_break_code, CEntryDebugBreakCode) \
V(FixedArray, number_string_cache, NumberStringCache) \
V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \
V(FixedArray, natives_source_cache, NativesSourceCache) \
V(Object, last_script_id, LastScriptId)
#define ROOT_LIST(V) \
STRONG_ROOT_LIST(V) \
V(Object, symbol_table)
V(SymbolTable, symbol_table, SymbolTable)
#define SYMBOL_LIST(V) \
V(Array_symbol, "Array") \
@ -636,18 +638,29 @@ class Heap : public AllStatic {
global_gc_epilogue_callback_ = callback;
}
// Heap roots
#define ROOT_ACCESSOR(type, name) static type* name() { return name##_; }
// Heap root getters. We have versions with and without type::cast() here.
// You can't use type::cast during GC because the assert fails.
#define ROOT_ACCESSOR(type, name, camel_name) \
static inline type* name() { \
return type::cast(roots_[k##camel_name##RootIndex]); \
} \
static inline type* raw_unchecked_##name() { \
return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]); \
}
ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
// Utility type maps
#define STRUCT_MAP_ACCESSOR(NAME, Name, name) \
static Map* name##_map() { return name##_map_; }
#define STRUCT_MAP_ACCESSOR(NAME, Name, name) \
static inline Map* name##_map() { \
return Map::cast(roots_[k##Name##MapRootIndex]); \
}
STRUCT_LIST(STRUCT_MAP_ACCESSOR)
#undef STRUCT_MAP_ACCESSOR
#define SYMBOL_ACCESSOR(name, str) static String* name() { return name##_; }
#define SYMBOL_ACCESSOR(name, str) static inline String* name() { \
return String::cast(roots_[k##name##RootIndex]); \
}
SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR
@ -692,11 +705,13 @@ class Heap : public AllStatic {
static inline AllocationSpace TargetSpaceId(InstanceType type);
// Sets the stub_cache_ (only used when expanding the dictionary).
static void set_code_stubs(NumberDictionary* value) { code_stubs_ = value; }
static void public_set_code_stubs(NumberDictionary* value) {
roots_[kCodeStubsRootIndex] = value;
}
// Sets the non_monomorphic_cache_ (only used when expanding the dictionary).
static void set_non_monomorphic_cache(NumberDictionary* value) {
non_monomorphic_cache_ = value;
static void public_set_non_monomorphic_cache(NumberDictionary* value) {
roots_[kNonMonomorphicCacheRootIndex] = value;
}
// Update the next script id.
@ -849,6 +864,13 @@ class Heap : public AllStatic {
static int mc_count_; // how many mark-compact collections happened
static int gc_count_; // how many gc happened
#define ROOT_ACCESSOR(type, name, camel_name) \
static inline void set_##name(type* value) { \
roots_[k##camel_name##RootIndex] = value; \
}
ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
#ifdef DEBUG
static bool allocation_allowed_;
@ -883,20 +905,49 @@ class Heap : public AllStatic {
// last GC.
static int old_gen_exhausted_;
// Declare all the roots
#define ROOT_DECLARATION(type, name) static type* name##_;
ROOT_LIST(ROOT_DECLARATION)
#undef ROOT_DECLARATION
// Declare all the root indices.
enum RootListIndex {
#define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex,
STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION)
#undef ROOT_INDEX_DECLARATION
// Utility type maps
#define DECLARE_STRUCT_MAP(NAME, Name, name) static Map* name##_map_;
#define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex,
STRUCT_LIST(DECLARE_STRUCT_MAP)
#undef DECLARE_STRUCT_MAP
#define SYMBOL_DECLARATION(name, str) static String* name##_;
SYMBOL_LIST(SYMBOL_DECLARATION)
#define SYMBOL_INDEX_DECLARATION(name, str) k##name##RootIndex,
SYMBOL_LIST(SYMBOL_INDEX_DECLARATION)
#undef SYMBOL_DECLARATION
kSymbolTableRootIndex,
kStrongRootListLength = kSymbolTableRootIndex,
kRootListLength
};
static Object* roots_[kRootListLength];
struct StringTypeTable {
InstanceType type;
int size;
RootListIndex index;
};
struct ConstantSymbolTable {
const char* contents;
RootListIndex index;
};
struct StructTable {
InstanceType type;
int size;
RootListIndex index;
};
static const StringTypeTable string_type_table[];
static const ConstantSymbolTable constant_symbol_table[];
static const StructTable struct_table[];
// The special hidden symbol which is an empty string, but does not match
// any string when looked up in properties.
static String* hidden_symbol_;

View File

@ -224,7 +224,9 @@ static inline HeapObject* ShortCircuitConsString(Object** p) {
if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object;
Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second();
if (reinterpret_cast<String*>(second) != Heap::empty_string()) return object;
if (second != Heap::raw_unchecked_empty_string()) {
return object;
}
// Since we don't have the object's start, it is impossible to update the
// remembered set. Therefore, we only replace the string with its left
@ -421,7 +423,7 @@ class SymbolTableCleaner : public ObjectVisitor {
}
}
// Set the entry to null_value (as deleted).
*p = Heap::null_value();
*p = Heap::raw_unchecked_null_value();
pointers_removed_++;
}
}
@ -475,7 +477,7 @@ void MarkCompactCollector::MarkDescriptorArray(
DescriptorArray* descriptors) {
if (descriptors->IsMarked()) return;
// Empty descriptor array is marked as a root before any maps are marked.
ASSERT(descriptors != Heap::empty_descriptor_array());
ASSERT(descriptors != Heap::raw_unchecked_empty_descriptor_array());
SetMark(descriptors);
FixedArray* contents = reinterpret_cast<FixedArray*>(
@ -590,7 +592,7 @@ void MarkCompactCollector::MarkSymbolTable() {
// and if it is a sliced string or a cons string backed by an
// external string (even indirectly), then the external string does
// not receive a weak reference callback.
SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table());
SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
// Mark the symbol table itself.
SetMark(symbol_table);
// Explicitly mark the prefix.
@ -780,10 +782,9 @@ void MarkCompactCollector::MarkLiveObjects() {
ProcessObjectGroups(root_visitor.stack_visitor());
// Prune the symbol table removing all symbols only pointed to by the
// symbol table. Cannot use SymbolTable::cast here because the symbol
// symbol table. Cannot use symbol_table() here because the symbol
// table is marked.
SymbolTable* symbol_table =
reinterpret_cast<SymbolTable*>(Heap::symbol_table());
SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
SymbolTableCleaner v;
symbol_table->IterateElements(&v);
symbol_table->ElementsRemoved(v.PointersRemoved());
@ -1142,11 +1143,11 @@ static void SweepSpace(NewSpace* space) {
// since their existing map might not be live after the collection.
int size = object->Size();
if (size >= ByteArray::kHeaderSize) {
object->set_map(Heap::byte_array_map());
object->set_map(Heap::raw_unchecked_byte_array_map());
ByteArray::cast(object)->set_length(ByteArray::LengthFor(size));
} else {
ASSERT(size == kPointerSize);
object->set_map(Heap::one_word_filler_map());
object->set_map(Heap::raw_unchecked_one_word_filler_map());
}
ASSERT(object->Size() == size);
}

View File

@ -481,7 +481,7 @@ bool Object::IsDictionary() {
bool Object::IsSymbolTable() {
return IsHashTable() && this == Heap::symbol_table();
return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
}
@ -2655,8 +2655,8 @@ void Map::ClearCodeCache() {
// No write barrier is needed since empty_fixed_array is not in new space.
// Please note this function is used during marking:
// - MarkCompactCollector::MarkUnmarkedObject
ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
WRITE_FIELD(this, kCodeCacheOffset, Heap::empty_fixed_array());
ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
}

View File

@ -4615,7 +4615,7 @@ void Map::ClearNonLiveTransitions(Object* real_prototype) {
// low-level accessors to get and modify their data.
DescriptorArray* d = reinterpret_cast<DescriptorArray*>(
*RawField(this, Map::kInstanceDescriptorsOffset));
if (d == Heap::empty_descriptor_array()) return;
if (d == Heap::raw_unchecked_empty_descriptor_array()) return;
Smi* NullDescriptorDetails =
PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi();
FixedArray* contents = reinterpret_cast<FixedArray*>(

View File

@ -297,97 +297,202 @@ enum PropertyNormalizationMode {
V(JS_FUNCTION_TYPE) \
// Since string types are not consecutive, this macro is used to
// iterate over them.
#define STRING_TYPE_LIST(V) \
V(SHORT_SYMBOL_TYPE, SeqTwoByteString::kAlignedSize, short_symbol) \
V(MEDIUM_SYMBOL_TYPE, SeqTwoByteString::kAlignedSize, medium_symbol) \
V(LONG_SYMBOL_TYPE, SeqTwoByteString::kAlignedSize, long_symbol) \
V(SHORT_ASCII_SYMBOL_TYPE, SeqAsciiString::kAlignedSize, short_ascii_symbol) \
V(SHORT_SYMBOL_TYPE, \
SeqTwoByteString::kAlignedSize, \
short_symbol, \
ShortSymbol) \
V(MEDIUM_SYMBOL_TYPE, \
SeqTwoByteString::kAlignedSize, \
medium_symbol, \
MediumSymbol) \
V(LONG_SYMBOL_TYPE, \
SeqTwoByteString::kAlignedSize, \
long_symbol, \
LongSymbol) \
V(SHORT_ASCII_SYMBOL_TYPE, \
SeqAsciiString::kAlignedSize, \
short_ascii_symbol, \
ShortAsciiSymbol) \
V(MEDIUM_ASCII_SYMBOL_TYPE, \
SeqAsciiString::kAlignedSize, \
medium_ascii_symbol) \
V(LONG_ASCII_SYMBOL_TYPE, SeqAsciiString::kAlignedSize, long_ascii_symbol) \
V(SHORT_CONS_SYMBOL_TYPE, ConsString::kSize, short_cons_symbol) \
V(MEDIUM_CONS_SYMBOL_TYPE, ConsString::kSize, medium_cons_symbol) \
V(LONG_CONS_SYMBOL_TYPE, ConsString::kSize, long_cons_symbol) \
V(SHORT_CONS_ASCII_SYMBOL_TYPE, ConsString::kSize, short_cons_ascii_symbol) \
V(MEDIUM_CONS_ASCII_SYMBOL_TYPE, ConsString::kSize, medium_cons_ascii_symbol)\
V(LONG_CONS_ASCII_SYMBOL_TYPE, ConsString::kSize, long_cons_ascii_symbol) \
V(SHORT_SLICED_SYMBOL_TYPE, SlicedString::kSize, short_sliced_symbol) \
V(MEDIUM_SLICED_SYMBOL_TYPE, SlicedString::kSize, medium_sliced_symbol) \
V(LONG_SLICED_SYMBOL_TYPE, SlicedString::kSize, long_sliced_symbol) \
medium_ascii_symbol, \
MediumAsciiSymbol) \
V(LONG_ASCII_SYMBOL_TYPE, \
SeqAsciiString::kAlignedSize, \
long_ascii_symbol, \
LongAsciiSymbol) \
V(SHORT_CONS_SYMBOL_TYPE, \
ConsString::kSize, \
short_cons_symbol, \
ShortConsSymbol) \
V(MEDIUM_CONS_SYMBOL_TYPE, \
ConsString::kSize, \
medium_cons_symbol, \
MediumConsSymbol) \
V(LONG_CONS_SYMBOL_TYPE, \
ConsString::kSize, \
long_cons_symbol, \
LongConsSymbol) \
V(SHORT_CONS_ASCII_SYMBOL_TYPE, \
ConsString::kSize, \
short_cons_ascii_symbol, \
ShortConsAsciiSymbol) \
V(MEDIUM_CONS_ASCII_SYMBOL_TYPE, \
ConsString::kSize, \
medium_cons_ascii_symbol, \
MediumConsAsciiSymbol) \
V(LONG_CONS_ASCII_SYMBOL_TYPE, \
ConsString::kSize, \
long_cons_ascii_symbol, \
LongConsAsciiSymbol) \
V(SHORT_SLICED_SYMBOL_TYPE, \
SlicedString::kSize, \
short_sliced_symbol, \
ShortSlicedSymbol) \
V(MEDIUM_SLICED_SYMBOL_TYPE, \
SlicedString::kSize, \
medium_sliced_symbol, \
MediumSlicedSymbol) \
V(LONG_SLICED_SYMBOL_TYPE, \
SlicedString::kSize, \
long_sliced_symbol, \
LongSlicedSymbol) \
V(SHORT_SLICED_ASCII_SYMBOL_TYPE, \
SlicedString::kSize, \
short_sliced_ascii_symbol) \
short_sliced_ascii_symbol, \
ShortSlicedAsciiSymbol) \
V(MEDIUM_SLICED_ASCII_SYMBOL_TYPE, \
SlicedString::kSize, \
medium_sliced_ascii_symbol) \
medium_sliced_ascii_symbol, \
MediumSlicedAsciiSymbol) \
V(LONG_SLICED_ASCII_SYMBOL_TYPE, \
SlicedString::kSize, \
long_sliced_ascii_symbol) \
long_sliced_ascii_symbol, \
LongSlicedAsciiSymbol) \
V(SHORT_EXTERNAL_SYMBOL_TYPE, \
ExternalTwoByteString::kSize, \
short_external_symbol) \
short_external_symbol, \
ShortExternalSymbol) \
V(MEDIUM_EXTERNAL_SYMBOL_TYPE, \
ExternalTwoByteString::kSize, \
medium_external_symbol) \
medium_external_symbol, \
MediumExternalSymbol) \
V(LONG_EXTERNAL_SYMBOL_TYPE, \
ExternalTwoByteString::kSize, \
long_external_symbol) \
long_external_symbol, \
LongExternalSymbol) \
V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE, \
ExternalAsciiString::kSize, \
short_external_ascii_symbol) \
short_external_ascii_symbol, \
ShortExternalAsciiSymbol) \
V(MEDIUM_EXTERNAL_ASCII_SYMBOL_TYPE, \
ExternalAsciiString::kSize, \
medium_external_ascii_symbol) \
medium_external_ascii_symbol, \
MediumExternalAsciiSymbol) \
V(LONG_EXTERNAL_ASCII_SYMBOL_TYPE, \
ExternalAsciiString::kSize, \
long_external_ascii_symbol) \
V(SHORT_STRING_TYPE, SeqTwoByteString::kAlignedSize, short_string) \
V(MEDIUM_STRING_TYPE, SeqTwoByteString::kAlignedSize, medium_string) \
V(LONG_STRING_TYPE, SeqTwoByteString::kAlignedSize, long_string) \
V(SHORT_ASCII_STRING_TYPE, SeqAsciiString::kAlignedSize, short_ascii_string) \
long_external_ascii_symbol, \
LongExternalAsciiSymbol) \
V(SHORT_STRING_TYPE, \
SeqTwoByteString::kAlignedSize, \
short_string, \
ShortString) \
V(MEDIUM_STRING_TYPE, \
SeqTwoByteString::kAlignedSize, \
medium_string, \
MediumString) \
V(LONG_STRING_TYPE, \
SeqTwoByteString::kAlignedSize, \
long_string, \
LongString) \
V(SHORT_ASCII_STRING_TYPE, \
SeqAsciiString::kAlignedSize, \
short_ascii_string, \
ShortAsciiString) \
V(MEDIUM_ASCII_STRING_TYPE, \
SeqAsciiString::kAlignedSize, \
medium_ascii_string) \
V(LONG_ASCII_STRING_TYPE, SeqAsciiString::kAlignedSize, long_ascii_string) \
V(SHORT_CONS_STRING_TYPE, ConsString::kSize, short_cons_string) \
V(MEDIUM_CONS_STRING_TYPE, ConsString::kSize, medium_cons_string) \
V(LONG_CONS_STRING_TYPE, ConsString::kSize, long_cons_string) \
V(SHORT_CONS_ASCII_STRING_TYPE, ConsString::kSize, short_cons_ascii_string) \
V(MEDIUM_CONS_ASCII_STRING_TYPE, ConsString::kSize, medium_cons_ascii_string)\
V(LONG_CONS_ASCII_STRING_TYPE, ConsString::kSize, long_cons_ascii_string) \
V(SHORT_SLICED_STRING_TYPE, SlicedString::kSize, short_sliced_string) \
V(MEDIUM_SLICED_STRING_TYPE, SlicedString::kSize, medium_sliced_string) \
V(LONG_SLICED_STRING_TYPE, SlicedString::kSize, long_sliced_string) \
medium_ascii_string, \
MediumAsciiString) \
V(LONG_ASCII_STRING_TYPE, \
SeqAsciiString::kAlignedSize, \
long_ascii_string, \
LongAsciiString) \
V(SHORT_CONS_STRING_TYPE, \
ConsString::kSize, \
short_cons_string, \
ShortConsString) \
V(MEDIUM_CONS_STRING_TYPE, \
ConsString::kSize, \
medium_cons_string, \
MediumConsString) \
V(LONG_CONS_STRING_TYPE, \
ConsString::kSize, \
long_cons_string, \
LongConsString) \
V(SHORT_CONS_ASCII_STRING_TYPE, \
ConsString::kSize, \
short_cons_ascii_string, \
ShortConsAsciiString) \
V(MEDIUM_CONS_ASCII_STRING_TYPE, \
ConsString::kSize, \
medium_cons_ascii_string, \
MediumConsAsciiString) \
V(LONG_CONS_ASCII_STRING_TYPE, \
ConsString::kSize, \
long_cons_ascii_string, \
LongConsAsciiString) \
V(SHORT_SLICED_STRING_TYPE, \
SlicedString::kSize, \
short_sliced_string, \
ShortSlicedString) \
V(MEDIUM_SLICED_STRING_TYPE, \
SlicedString::kSize, \
medium_sliced_string, \
MediumSlicedString) \
V(LONG_SLICED_STRING_TYPE, \
SlicedString::kSize, \
long_sliced_string, \
LongSlicedString) \
V(SHORT_SLICED_ASCII_STRING_TYPE, \
SlicedString::kSize, \
short_sliced_ascii_string) \
short_sliced_ascii_string, \
ShortSlicedAsciiString) \
V(MEDIUM_SLICED_ASCII_STRING_TYPE, \
SlicedString::kSize, \
medium_sliced_ascii_string) \
medium_sliced_ascii_string, \
MediumSlicedAsciiString) \
V(LONG_SLICED_ASCII_STRING_TYPE, \
SlicedString::kSize, \
long_sliced_ascii_string) \
long_sliced_ascii_string, \
LongSlicedAsciiString) \
V(SHORT_EXTERNAL_STRING_TYPE, \
ExternalTwoByteString::kSize, \
short_external_string) \
short_external_string, \
ShortExternalString) \
V(MEDIUM_EXTERNAL_STRING_TYPE, \
ExternalTwoByteString::kSize, \
medium_external_string) \
medium_external_string, \
MediumExternalString) \
V(LONG_EXTERNAL_STRING_TYPE, \
ExternalTwoByteString::kSize, \
long_external_string) \
long_external_string, \
LongExternalString) \
V(SHORT_EXTERNAL_ASCII_STRING_TYPE, \
ExternalAsciiString::kSize, \
short_external_ascii_string) \
short_external_ascii_string, \
ShortExternalAsciiString) \
V(MEDIUM_EXTERNAL_ASCII_STRING_TYPE, \
ExternalAsciiString::kSize, \
medium_external_ascii_string) \
medium_external_ascii_string, \
MediumExternalAsciiString) \
V(LONG_EXTERNAL_ASCII_STRING_TYPE, \
ExternalAsciiString::kSize, \
long_external_ascii_string)
long_external_ascii_string, \
LongExternalAsciiString)
// A struct is a simple object a set of object-valued fields. Including an
// object type in this causes the compiler to generate most of the boilerplate

View File

@ -1141,7 +1141,7 @@ static void ReportHistogram(bool print_spill) {
// Summarize string types.
int string_number = 0;
int string_bytes = 0;
#define INCREMENT(type, size, name) \
#define INCREMENT(type, size, name, camel_name) \
string_number += heap_histograms[type].number(); \
string_bytes += heap_histograms[type].bytes();
STRING_TYPE_LIST(INCREMENT)
@ -1185,8 +1185,8 @@ static void DoReportStatistics(HistogramInfo* info, const char* description) {
// Lump all the string types together.
int string_number = 0;
int string_bytes = 0;
#define INCREMENT(type, size, name) \
string_number += info[type].number(); \
#define INCREMENT(type, size, name, camel_name) \
string_number += info[type].number(); \
string_bytes += info[type].bytes();
STRING_TYPE_LIST(INCREMENT)
#undef INCREMENT
@ -1266,12 +1266,12 @@ void FreeListNode::set_size(int size_in_bytes) {
// field and a next pointer, we give it a filler map that gives it the
// correct size.
if (size_in_bytes > ByteArray::kHeaderSize) {
set_map(Heap::byte_array_map());
set_map(Heap::raw_unchecked_byte_array_map());
ByteArray::cast(this)->set_length(ByteArray::LengthFor(size_in_bytes));
} else if (size_in_bytes == kPointerSize) {
set_map(Heap::one_word_filler_map());
set_map(Heap::raw_unchecked_one_word_filler_map());
} else if (size_in_bytes == 2 * kPointerSize) {
set_map(Heap::two_word_filler_map());
set_map(Heap::raw_unchecked_two_word_filler_map());
} else {
UNREACHABLE();
}
@ -1280,14 +1280,14 @@ void FreeListNode::set_size(int size_in_bytes) {
Address FreeListNode::next() {
ASSERT(map() == Heap::byte_array_map());
ASSERT(map() == Heap::raw_unchecked_byte_array_map());
ASSERT(Size() >= kNextOffset + kPointerSize);
return Memory::Address_at(address() + kNextOffset);
}
void FreeListNode::set_next(Address next) {
ASSERT(map() == Heap::byte_array_map());
ASSERT(map() == Heap::raw_unchecked_byte_array_map());
ASSERT(Size() >= kNextOffset + kPointerSize);
Memory::Address_at(address() + kNextOffset) = next;
}
@ -1856,7 +1856,7 @@ void OldSpace::ReportStatistics() {
int bitpos = intoff*kBitsPerByte + bitoff;
Address slot = p->OffsetToAddress(bitpos << kObjectAlignmentBits);
Object** obj = reinterpret_cast<Object**>(slot);
if (*obj == Heap::fixed_array_map()) {
if (*obj == Heap::raw_unchecked_fixed_array_map()) {
rset_marked_arrays++;
FixedArray* fa = FixedArray::cast(HeapObject::FromAddress(slot));

View File

@ -562,10 +562,11 @@ Object* StubCache::ComputeCallGlobal(int argc,
static Object* GetProbeValue(Code::Flags flags) {
NumberDictionary* dictionary = Heap::non_monomorphic_cache();
// Use raw_unchecked... so we don't get assert failures during GC.
NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache();
int entry = dictionary->FindEntry(flags);
if (entry != -1) return dictionary->ValueAt(entry);
return Heap::undefined_value();
return Heap::raw_unchecked_undefined_value();
}
@ -579,7 +580,7 @@ static Object* ProbeCache(Code::Flags flags) {
Heap::non_monomorphic_cache()->AtNumberPut(flags,
Heap::undefined_value());
if (result->IsFailure()) return result;
Heap::set_non_monomorphic_cache(NumberDictionary::cast(result));
Heap::public_set_non_monomorphic_cache(NumberDictionary::cast(result));
return probe;
}