* 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:
parent
bf656d2ae1
commit
8f73ae0325
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
260
src/heap.cc
260
src/heap.cc
@ -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,7 +3366,7 @@ void HeapProfiler::WriteSample() {
|
||||
// Lump all the string types together.
|
||||
int string_number = 0;
|
||||
int string_bytes = 0;
|
||||
#define INCREMENT_SIZE(type, size, name) \
|
||||
#define INCREMENT_SIZE(type, size, name, camel_name) \
|
||||
string_number += info[type].number(); \
|
||||
string_bytes += info[type].bytes();
|
||||
STRING_TYPE_LIST(INCREMENT_SIZE)
|
||||
|
267
src/heap.h
267
src/heap.h
@ -35,104 +35,106 @@ 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)
|
||||
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_; }
|
||||
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_;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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*>(
|
||||
|
201
src/objects.h
201
src/objects.h
@ -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
|
||||
|
@ -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,7 +1185,7 @@ 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) \
|
||||
#define INCREMENT(type, size, name, camel_name) \
|
||||
string_number += info[type].number(); \
|
||||
string_bytes += info[type].bytes();
|
||||
STRING_TYPE_LIST(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));
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user