Commit 83c63cf5 authored by ulan@chromium.org's avatar ulan@chromium.org

Out-of-line constant pool on Arm: Stage 2 - Introduce ConstantPoolArray object.

Second stage of implementing an out-of-line constant pool on Arm.  This CL
Introduces the ConstantPoolArray object which will be used as the backing
store of out-of-line constant pools.  Nothing uses this object yet.

BUG=
R=ulan@chromium.org

Review URL: https://chromiumcodereview.appspot.com/22601003

Patch from Ross McIlroy <rmcilroy@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17197 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 63305af0
......@@ -5393,7 +5393,7 @@ class Internals {
static const int kNullValueRootIndex = 7;
static const int kTrueValueRootIndex = 8;
static const int kFalseValueRootIndex = 9;
static const int kEmptyStringRootIndex = 131;
static const int kEmptyStringRootIndex = 132;
static const int kNodeClassIdOffset = 1 * kApiPointerSize;
static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
......@@ -5404,7 +5404,7 @@ class Internals {
static const int kNodeIsIndependentShift = 4;
static const int kNodeIsPartiallyDependentShift = 5;
static const int kJSObjectType = 0xb1;
static const int kJSObjectType = 0xb2;
static const int kFirstNonstringType = 0x80;
static const int kOddballType = 0x83;
static const int kForeignType = 0x87;
......
......@@ -79,6 +79,21 @@ Handle<FixedDoubleArray> Factory::NewFixedDoubleArray(int size,
}
Handle<ConstantPoolArray> Factory::NewConstantPoolArray(
int number_of_int64_entries,
int number_of_ptr_entries,
int number_of_int32_entries) {
ASSERT(number_of_int64_entries > 0 || number_of_ptr_entries > 0 ||
number_of_int32_entries > 0);
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateConstantPoolArray(number_of_int64_entries,
number_of_ptr_entries,
number_of_int32_entries),
ConstantPoolArray);
}
Handle<NameDictionary> Factory::NewNameDictionary(int at_least_space_for) {
ASSERT(0 <= at_least_space_for);
CALL_HEAP_FUNCTION(isolate(),
......@@ -624,6 +639,12 @@ Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray(
}
Handle<ConstantPoolArray> Factory::CopyConstantPoolArray(
Handle<ConstantPoolArray> array) {
CALL_HEAP_FUNCTION(isolate(), array->Copy(), ConstantPoolArray);
}
Handle<JSFunction> Factory::BaseNewFunctionFromSharedFunctionInfo(
Handle<SharedFunctionInfo> function_info,
Handle<Map> function_map,
......
......@@ -59,6 +59,11 @@ class Factory {
int size,
PretenureFlag pretenure = NOT_TENURED);
Handle<ConstantPoolArray> NewConstantPoolArray(
int number_of_int64_entries,
int number_of_ptr_entries,
int number_of_int32_entries);
Handle<SeededNumberDictionary> NewSeededNumberDictionary(
int at_least_space_for);
......@@ -273,6 +278,9 @@ class Factory {
Handle<FixedDoubleArray> CopyFixedDoubleArray(
Handle<FixedDoubleArray> array);
Handle<ConstantPoolArray> CopyConstantPoolArray(
Handle<ConstantPoolArray> array);
// Numbers (e.g. literals) are pretenured by the parser.
Handle<Object> NewNumber(double value,
PretenureFlag pretenure = NOT_TENURED);
......
......@@ -232,6 +232,8 @@ const uint32_t kMaxUInt32 = 0xFFFFFFFFu;
const int kCharSize = sizeof(char); // NOLINT
const int kShortSize = sizeof(short); // NOLINT
const int kIntSize = sizeof(int); // NOLINT
const int kInt32Size = sizeof(int32_t); // NOLINT
const int kInt64Size = sizeof(int64_t); // NOLINT
const int kDoubleSize = sizeof(double); // NOLINT
const int kIntptrSize = sizeof(intptr_t); // NOLINT
const int kPointerSize = sizeof(void*); // NOLINT
......
......@@ -206,6 +206,11 @@ MaybeObject* Heap::CopyFixedDoubleArray(FixedDoubleArray* src) {
}
MaybeObject* Heap::CopyConstantPoolArray(ConstantPoolArray* src) {
return CopyConstantPoolArrayWithMap(src, src->map());
}
MaybeObject* Heap::AllocateRaw(int size_in_bytes,
AllocationSpace space,
AllocationSpace retry_space) {
......
......@@ -1957,6 +1957,7 @@ Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
STATIC_ASSERT((FixedDoubleArray::kHeaderSize & kDoubleAlignmentMask) == 0);
STATIC_ASSERT((ConstantPoolArray::kHeaderSize & kDoubleAlignmentMask) == 0);
INLINE(static HeapObject* EnsureDoubleAligned(Heap* heap,
......@@ -2657,6 +2658,12 @@ bool Heap::CreateInitialMaps() {
}
set_fixed_double_array_map(Map::cast(obj));
{ MaybeObject* maybe_obj =
AllocateMap(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_constant_pool_array_map(Map::cast(obj));
{ MaybeObject* maybe_obj =
AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
......@@ -5384,6 +5391,27 @@ MaybeObject* Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src,
}
MaybeObject* Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src,
Map* map) {
int int64_entries = src->count_of_int64_entries();
int ptr_entries = src->count_of_ptr_entries();
int int32_entries = src->count_of_int32_entries();
Object* obj;
{ MaybeObject* maybe_obj =
AllocateConstantPoolArray(int64_entries, ptr_entries, int32_entries);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
HeapObject* dst = HeapObject::cast(obj);
dst->set_map_no_write_barrier(map);
CopyBlock(
dst->address() + ConstantPoolArray::kLengthOffset,
src->address() + ConstantPoolArray::kLengthOffset,
ConstantPoolArray::SizeFor(int64_entries, ptr_entries, int32_entries)
- ConstantPoolArray::kLengthOffset);
return obj;
}
MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) {
if (length < 0 || length > FixedArray::kMaxLength) {
return Failure::OutOfMemoryException(0xe);
......@@ -5515,6 +5543,40 @@ MaybeObject* Heap::AllocateRawFixedDoubleArray(int length,
}
MaybeObject* Heap::AllocateConstantPoolArray(int number_of_int64_entries,
int number_of_ptr_entries,
int number_of_int32_entries) {
ASSERT(number_of_int64_entries > 0 || number_of_ptr_entries > 0 ||
number_of_int32_entries > 0);
int size = ConstantPoolArray::SizeFor(number_of_int64_entries,
number_of_ptr_entries,
number_of_int32_entries);
#ifndef V8_HOST_ARCH_64_BIT
size += kPointerSize;
#endif
HeapObject* object;
{ MaybeObject* maybe_object = old_pointer_space_->AllocateRaw(size);
if (!maybe_object->To<HeapObject>(&object)) return maybe_object;
}
object = EnsureDoubleAligned(this, object, size);
HeapObject::cast(object)->set_map_no_write_barrier(constant_pool_array_map());
ConstantPoolArray* constant_pool =
reinterpret_cast<ConstantPoolArray*>(object);
constant_pool->SetEntryCounts(number_of_int64_entries,
number_of_ptr_entries,
number_of_int32_entries);
MemsetPointer(
HeapObject::RawField(
constant_pool,
constant_pool->OffsetOfElementAt(constant_pool->first_ptr_index())),
undefined_value(),
number_of_ptr_entries);
return constant_pool;
}
MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
Object* result;
{ MaybeObject* maybe_result = AllocateFixedArray(length, pretenure);
......
......@@ -71,6 +71,7 @@ namespace internal {
V(Map, scope_info_map, ScopeInfoMap) \
V(Map, fixed_cow_array_map, FixedCOWArrayMap) \
V(Map, fixed_double_array_map, FixedDoubleArrayMap) \
V(Map, constant_pool_array_map, ConstantPoolArrayMap) \
V(Object, no_interceptor_result_sentinel, NoInterceptorResultSentinel) \
V(Map, hash_table_map, HashTableMap) \
V(FixedArray, empty_fixed_array, EmptyFixedArray) \
......@@ -943,6 +944,16 @@ class Heap {
MUST_USE_RESULT MaybeObject* CopyFixedDoubleArrayWithMap(
FixedDoubleArray* src, Map* map);
// Make a copy of src and return it. Returns
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
MUST_USE_RESULT inline MaybeObject* CopyConstantPoolArray(
ConstantPoolArray* src);
// Make a copy of src, set the map, and return the copy. Returns
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
MUST_USE_RESULT MaybeObject* CopyConstantPoolArrayWithMap(
ConstantPoolArray* src, Map* map);
// Allocates a fixed array initialized with the hole values.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
......@@ -951,6 +962,11 @@ class Heap {
int length,
PretenureFlag pretenure = NOT_TENURED);
MUST_USE_RESULT MaybeObject* AllocateConstantPoolArray(
int first_int64_index,
int first_ptr_index,
int first_int32_index);
// Allocates a fixed double array with uninitialized values. Returns
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
// Please note this does not perform a garbage collection.
......
......@@ -95,6 +95,9 @@ void HeapObject::HeapObjectVerify() {
case FIXED_DOUBLE_ARRAY_TYPE:
FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
break;
case CONSTANT_POOL_ARRAY_TYPE:
ConstantPoolArray::cast(this)->ConstantPoolArrayVerify();
break;
case BYTE_ARRAY_TYPE:
ByteArray::cast(this)->ByteArrayVerify();
break;
......@@ -439,6 +442,11 @@ void FixedDoubleArray::FixedDoubleArrayVerify() {
}
void ConstantPoolArray::ConstantPoolArrayVerify() {
CHECK(IsConstantPoolArray());
}
void JSGeneratorObject::JSGeneratorObjectVerify() {
// In an expression like "new g()", there can be a point where a generator
// object is allocated but its fields are all undefined, as it hasn't yet been
......
......@@ -133,7 +133,7 @@ PropertyDetails PropertyDetails::AsDeleted() {
bool Object::IsFixedArrayBase() {
return IsFixedArray() || IsFixedDoubleArray();
return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray();
}
......@@ -571,6 +571,7 @@ TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
TYPE_CHECKER(Map, MAP_TYPE)
TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
TYPE_CHECKER(ConstantPoolArray, CONSTANT_POOL_ARRAY_TYPE)
bool Object::IsJSWeakCollection() {
......@@ -1027,6 +1028,12 @@ MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) {
#define WRITE_UINT32_FIELD(p, offset, value) \
(*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
#define READ_INT32_FIELD(p, offset) \
(*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)))
#define WRITE_INT32_FIELD(p, offset, value) \
(*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)) = value)
#define READ_INT64_FIELD(p, offset) \
(*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
......@@ -1887,7 +1894,8 @@ void Object::VerifyApiCallResultType() {
FixedArrayBase* FixedArrayBase::cast(Object* object) {
ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray() ||
object->IsConstantPoolArray());
return reinterpret_cast<FixedArrayBase*>(object);
}
......@@ -1986,6 +1994,98 @@ bool FixedDoubleArray::is_the_hole(int index) {
}
SMI_ACCESSORS(ConstantPoolArray, first_ptr_index, kFirstPointerIndexOffset)
SMI_ACCESSORS(ConstantPoolArray, first_int32_index, kFirstInt32IndexOffset)
int ConstantPoolArray::first_int64_index() {
return 0;
}
int ConstantPoolArray::count_of_int64_entries() {
return first_ptr_index();
}
int ConstantPoolArray::count_of_ptr_entries() {
return first_int32_index() - first_ptr_index();
}
int ConstantPoolArray::count_of_int32_entries() {
return length() - first_int32_index();
}
void ConstantPoolArray::SetEntryCounts(int number_of_int64_entries,
int number_of_ptr_entries,
int number_of_int32_entries) {
set_first_ptr_index(number_of_int64_entries);
set_first_int32_index(number_of_int64_entries + number_of_ptr_entries);
set_length(number_of_int64_entries + number_of_ptr_entries +
number_of_int32_entries);
}
int64_t ConstantPoolArray::get_int64_entry(int index) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(index >= 0 && index < first_ptr_index());
return READ_INT64_FIELD(this, OffsetOfElementAt(index));
}
double ConstantPoolArray::get_int64_entry_as_double(int index) {
STATIC_ASSERT(kDoubleSize == kInt64Size);
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(index >= 0 && index < first_ptr_index());
return READ_DOUBLE_FIELD(this, OffsetOfElementAt(index));
}
Object* ConstantPoolArray::get_ptr_entry(int index) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(index >= first_ptr_index() && index < first_int32_index());
return READ_FIELD(this, OffsetOfElementAt(index));
}
int32_t ConstantPoolArray::get_int32_entry(int index) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(index >= first_int32_index() && index < length());
return READ_INT32_FIELD(this, OffsetOfElementAt(index));
}
void ConstantPoolArray::set(int index, Object* value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(index >= first_ptr_index() && index < first_int32_index());
WRITE_FIELD(this, OffsetOfElementAt(index), value);
WRITE_BARRIER(GetHeap(), this, OffsetOfElementAt(index), value);
}
void ConstantPoolArray::set(int index, int64_t value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(index >= first_int64_index() && index < first_ptr_index());
WRITE_INT64_FIELD(this, OffsetOfElementAt(index), value);
}
void ConstantPoolArray::set(int index, double value) {
STATIC_ASSERT(kDoubleSize == kInt64Size);
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(index >= first_int64_index() && index < first_ptr_index());
WRITE_DOUBLE_FIELD(this, OffsetOfElementAt(index), value);
}
void ConstantPoolArray::set(int index, int32_t value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(index >= this->first_int32_index() && index < length());
WRITE_INT32_FIELD(this, OffsetOfElementAt(index), value);
}
WriteBarrierMode HeapObject::GetWriteBarrierMode(
const DisallowHeapAllocation& promise) {
Heap* heap = GetHeap();
......@@ -2478,6 +2578,7 @@ void SeededNumberDictionary::set_requires_slow_elements() {
CAST_ACCESSOR(FixedArray)
CAST_ACCESSOR(FixedDoubleArray)
CAST_ACCESSOR(ConstantPoolArray)
CAST_ACCESSOR(DescriptorArray)
CAST_ACCESSOR(DeoptimizationInputData)
CAST_ACCESSOR(DeoptimizationOutputData)
......@@ -3373,6 +3474,12 @@ int HeapObject::SizeFromMap(Map* map) {
return FixedDoubleArray::SizeFor(
reinterpret_cast<FixedDoubleArray*>(this)->length());
}
if (instance_type == CONSTANT_POOL_ARRAY_TYPE) {
return ConstantPoolArray::SizeFor(
reinterpret_cast<ConstantPoolArray*>(this)->count_of_int64_entries(),
reinterpret_cast<ConstantPoolArray*>(this)->count_of_ptr_entries(),
reinterpret_cast<ConstantPoolArray*>(this)->count_of_int32_entries());
}
ASSERT(instance_type == CODE_TYPE);
return reinterpret_cast<Code*>(this)->CodeSize();
}
......@@ -6052,6 +6159,12 @@ MaybeObject* FixedDoubleArray::Copy() {
}
MaybeObject* ConstantPoolArray::Copy() {
if (length() == 0) return this;
return GetHeap()->CopyConstantPoolArray(this);
}
void TypeFeedbackCells::SetAstId(int index, TypeFeedbackId id) {
set(1 + index * 2, Smi::FromInt(id.ToInt()));
}
......
......@@ -95,6 +95,9 @@ void HeapObject::HeapObjectPrint(FILE* out) {
case FIXED_DOUBLE_ARRAY_TYPE:
FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(out);
break;
case CONSTANT_POOL_ARRAY_TYPE:
ConstantPoolArray::cast(this)->ConstantPoolArrayPrint(out);
break;
case FIXED_ARRAY_TYPE:
FixedArray::cast(this)->FixedArrayPrint(out);
break;
......@@ -630,6 +633,23 @@ void FixedDoubleArray::FixedDoubleArrayPrint(FILE* out) {
}
void ConstantPoolArray::ConstantPoolArrayPrint(FILE* out) {
HeapObject::PrintHeader(out, "ConstantPoolArray");
PrintF(out, " - length: %d", length());
for (int i = 0; i < length(); i++) {
if (i < first_ptr_index()) {
PrintF(out, "\n [%d]: double: %g", i, get_int64_entry_as_double(i));
} else if (i < first_int32_index()) {
PrintF(out, "\n [%d]: pointer: %p", i,
reinterpret_cast<void*>(get_ptr_entry(i)));
} else {
PrintF(out, "\n [%d]: int32: %d", i, get_int32_entry(i));
}
}
PrintF(out, "\n");
}
void JSValue::JSValuePrint(FILE* out) {
HeapObject::PrintHeader(out, "ValueObject");
value()->Print(out);
......
......@@ -185,6 +185,8 @@ void StaticMarkingVisitor<StaticVisitor>::Initialize() {
table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit);
table_.Register(kVisitConstantPoolArray, &VisitConstantPoolArray);
table_.Register(kVisitNativeContext, &VisitNativeContext);
table_.Register(kVisitAllocationSite,
......@@ -449,6 +451,22 @@ void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfo(
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitConstantPoolArray(
Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
int first_ptr_offset = constant_pool->OffsetOfElementAt(
constant_pool->first_ptr_index());
int last_ptr_offset = constant_pool->OffsetOfElementAt(
constant_pool->first_ptr_index() + constant_pool->count_of_ptr_entries());
StaticVisitor::VisitPointers(
heap,
HeapObject::RawField(object, first_ptr_offset),
HeapObject::RawField(object, last_ptr_offset));
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitJSFunction(
Map* map, HeapObject* object) {
......
......@@ -82,6 +82,9 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId(
case FIXED_DOUBLE_ARRAY_TYPE:
return kVisitFixedDoubleArray;
case CONSTANT_POOL_ARRAY_TYPE:
return kVisitConstantPoolArray;
case ODDBALL_TYPE:
return kVisitOddball;
......
......@@ -54,6 +54,7 @@ class StaticVisitorBase : public AllStatic {
V(FreeSpace) \
V(FixedArray) \
V(FixedDoubleArray) \
V(ConstantPoolArray) \
V(NativeContext) \
V(AllocationSite) \
V(DataObject2) \
......@@ -416,6 +417,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
INLINE(static void VisitMap(Map* map, HeapObject* object));
INLINE(static void VisitCode(Map* map, HeapObject* object));
INLINE(static void VisitSharedFunctionInfo(Map* map, HeapObject* object));
INLINE(static void VisitConstantPoolArray(Map* map, HeapObject* object));
INLINE(static void VisitJSFunction(Map* map, HeapObject* object));
INLINE(static void VisitJSRegExp(Map* map, HeapObject* object));
INLINE(static void VisitJSArrayBuffer(Map* map, HeapObject* object));
......
......@@ -1737,6 +1737,9 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
case FIXED_ARRAY_TYPE:
FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
break;
case CONSTANT_POOL_ARRAY_TYPE:
reinterpret_cast<ConstantPoolArray*>(this)->ConstantPoolIterateBody(v);
break;
case FIXED_DOUBLE_ARRAY_TYPE:
break;
case JS_OBJECT_TYPE:
......@@ -9362,6 +9365,16 @@ bool Map::EquivalentToForNormalization(Map* other,
}
void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
int first_ptr_offset = OffsetOfElementAt(first_ptr_index());
int last_ptr_offset =
OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries());
v->VisitPointers(
HeapObject::RawField(this, first_ptr_offset),
HeapObject::RawField(this, last_ptr_offset));
}
void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
// Iterate over all fields in the body but take care in dealing with
// the code entry.
......
......@@ -405,6 +405,7 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
\
V(FIXED_ARRAY_TYPE) \
V(FIXED_DOUBLE_ARRAY_TYPE) \
V(CONSTANT_POOL_ARRAY_TYPE) \
V(SHARED_FUNCTION_INFO_TYPE) \
\
V(JS_MESSAGE_OBJECT_TYPE) \
......@@ -715,6 +716,7 @@ enum InstanceType {
EXTERNAL_DOUBLE_ARRAY_TYPE,
EXTERNAL_PIXEL_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE
FIXED_DOUBLE_ARRAY_TYPE,
CONSTANT_POOL_ARRAY_TYPE,
FILLER_TYPE, // LAST_DATA_TYPE
// Structs.
......@@ -1000,6 +1002,7 @@ class MaybeObject BASE_EMBEDDED {
V(TypeFeedbackCells) \
V(FixedArray) \
V(FixedDoubleArray) \
V(ConstantPoolArray) \
V(Context) \
V(NativeContext) \
V(ScopeInfo) \
......@@ -3032,6 +3035,100 @@ class FixedDoubleArray: public FixedArrayBase {
};
// ConstantPoolArray describes a fixed-sized array containing constant pool
// entires.
// The format of the pool is:
// [0]: Field holding the first index which is a pointer entry
// [1]: Field holding the first index which is a int32 entry
// [2] ... [first_ptr_index() - 1]: 64 bit entries
// [first_ptr_index()] ... [first_int32_index() - 1]: pointer entries
// [first_int32_index()] ... [length - 1]: 32 bit entries
class ConstantPoolArray: public FixedArrayBase {
public:
// Getters for the field storing the first index for different type entries.
inline int first_ptr_index();
inline int first_int64_index();
inline int first_int32_index();
// Getters for counts of different type entries.
inline int count_of_ptr_entries();
inline int count_of_int64_entries();
inline int count_of_int32_entries();
// Setter and getter for pool elements.
inline Object* get_ptr_entry(int index);
inline int64_t get_int64_entry(int index);
inline int32_t get_int32_entry(int index);
inline double get_int64_entry_as_double(int index);
inline void set(int index, Object* value);
inline void set(int index, int64_t value);
inline void set(int index, double value);
inline void set(int index, int32_t value);
// Set up initial state.
inline void SetEntryCounts(int number_of_int64_entries,
int number_of_ptr_entries,
int number_of_int32_entries);
// Copy operations
MUST_USE_RESULT inline MaybeObject* Copy();
// Garbage collection support.
inline static int SizeFor(int number_of_int64_entries,
int number_of_ptr_entries,
int number_of_int32_entries) {
return RoundUp(OffsetAt(number_of_int64_entries,
number_of_ptr_entries,
number_of_int32_entries),
kPointerSize);
}
// Code Generation support.
inline int OffsetOfElementAt(int index) {
ASSERT(index < length());
if (index >= first_int32_index()) {
return OffsetAt(count_of_int64_entries(), count_of_ptr_entries(),
index - first_int32_index());
} else if (index >= first_ptr_index()) {
return OffsetAt(count_of_int64_entries(), index - first_ptr_index(), 0);
} else {
return OffsetAt(index, 0, 0);
}
}
// Casting.
static inline ConstantPoolArray* cast(Object* obj);
// Layout description.
static const int kFirstPointerIndexOffset = FixedArray::kHeaderSize;
static const int kFirstInt32IndexOffset =
kFirstPointerIndexOffset + kPointerSize;
static const int kFirstOffset = kFirstInt32IndexOffset + kPointerSize;
// Dispatched behavior.
void ConstantPoolIterateBody(ObjectVisitor* v);
DECLARE_PRINTER(ConstantPoolArray)
DECLARE_VERIFIER(ConstantPoolArray)
private:
inline void set_first_ptr_index(int value);
inline void set_first_int32_index(int value);
inline static int OffsetAt(int number_of_int64_entries,
int number_of_ptr_entries,
int number_of_int32_entries) {
return kFirstOffset
+ (number_of_int64_entries * kInt64Size)
+ (number_of_ptr_entries * kPointerSize)
+ (number_of_int32_entries * kInt32Size);
}
DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolArray);
};
// DescriptorArrays are fixed arrays used to hold instance descriptors.
// The format of the these objects is:
// [0]: Number of descriptors
......
......@@ -41,6 +41,7 @@ Address StoreBuffer::TopAddress() {
void StoreBuffer::Mark(Address addr) {
ASSERT(!heap_->cell_space()->Contains(addr));
ASSERT(!heap_->code_space()->Contains(addr));
ASSERT(!heap_->old_data_space()->Contains(addr));
Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top());
*top++ = addr;
heap_->public_set_store_buffer_top(top);
......
......@@ -56,6 +56,7 @@
'test-circular-queue.cc',
'test-compiler.cc',
'test-condition-variable.cc',
'test-constantpool.cc',
'test-conversions.cc',
'test-cpu.cc',
'test-cpu-profiler.cc',
......
// Copyright 2013 the V8 project authors. All rights reserved.
// Test constant pool array code.
#include "v8.h"
#include "factory.h"
#include "objects.h"
#include "cctest.h"
using namespace v8::internal;
TEST(ConstantPool) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
Factory* factory = isolate->factory();
v8::HandleScope scope(context->GetIsolate());
// Check construction.
Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(3, 2, 1);
CHECK_EQ(array->count_of_int64_entries(), 3);
CHECK_EQ(array->count_of_ptr_entries(), 2);
CHECK_EQ(array->count_of_int32_entries(), 1);
CHECK_EQ(array->length(), 6);
CHECK_EQ(array->first_int64_index(), 0);
CHECK_EQ(array->first_ptr_index(), 3);
CHECK_EQ(array->first_int32_index(), 5);
// Check getters and setters.
int64_t big_number = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
Handle<Object> object = factory->NewHeapNumber(4.0);
array->set(0, big_number);
array->set(1, 0.5);
array->set(3, *object);
array->set(5, 50);
CHECK_EQ(array->get_int64_entry(0), big_number);
CHECK_EQ(array->get_int64_entry_as_double(1), 0.5);
CHECK_EQ(array->get_ptr_entry(3), *object);
CHECK_EQ(array->get_int32_entry(5), 50);
// Check pointers are updated on GC.
Object* old_ptr = array->get_ptr_entry(3);
CHECK_EQ(*object, old_ptr);
heap->CollectGarbage(NEW_SPACE);
Object* new_ptr = array->get_ptr_entry(3);
CHECK_NE(*object, old_ptr);
CHECK_EQ(*object, new_ptr);
}
......@@ -71,53 +71,54 @@ INSTANCE_TYPES = {
144: "EXTERNAL_FLOAT_ARRAY_TYPE",
145: "EXTERNAL_DOUBLE_ARRAY_TYPE",
146: "EXTERNAL_PIXEL_ARRAY_TYPE",
148: "FILLER_TYPE",
149: "DECLARED_ACCESSOR_DESCRIPTOR_TYPE",
150: "DECLARED_ACCESSOR_INFO_TYPE",
151: "EXECUTABLE_ACCESSOR_INFO_TYPE",
152: "ACCESSOR_PAIR_TYPE",
153: "ACCESS_CHECK_INFO_TYPE",
154: "INTERCEPTOR_INFO_TYPE",
155: "CALL_HANDLER_INFO_TYPE",
156: "FUNCTION_TEMPLATE_INFO_TYPE",
157: "OBJECT_TEMPLATE_INFO_TYPE",
158: "SIGNATURE_INFO_TYPE",
159: "TYPE_SWITCH_INFO_TYPE",
161: "ALLOCATION_MEMENTO_TYPE",
160: "ALLOCATION_SITE_TYPE",
162: "SCRIPT_TYPE",
163: "CODE_CACHE_TYPE",
164: "POLYMORPHIC_CODE_CACHE_TYPE",
165: "TYPE_FEEDBACK_INFO_TYPE",
166: "ALIASED_ARGUMENTS_ENTRY_TYPE",
167: "BOX_TYPE",
170: "FIXED_ARRAY_TYPE",
149: "FILLER_TYPE",
150: "DECLARED_ACCESSOR_DESCRIPTOR_TYPE",
151: "DECLARED_ACCESSOR_INFO_TYPE",
152: "EXECUTABLE_ACCESSOR_INFO_TYPE",
153: "ACCESSOR_PAIR_TYPE",
154: "ACCESS_CHECK_INFO_TYPE",
155: "INTERCEPTOR_INFO_TYPE",
156: "CALL_HANDLER_INFO_TYPE",
157: "FUNCTION_TEMPLATE_INFO_TYPE",
158: "OBJECT_TEMPLATE_INFO_TYPE",
159: "SIGNATURE_INFO_TYPE",
160: "TYPE_SWITCH_INFO_TYPE",
162: "ALLOCATION_MEMENTO_TYPE",
161: "ALLOCATION_SITE_TYPE",
163: "SCRIPT_TYPE",
164: "CODE_CACHE_TYPE",
165: "POLYMORPHIC_CODE_CACHE_TYPE",
166: "TYPE_FEEDBACK_INFO_TYPE",
167: "ALIASED_ARGUMENTS_ENTRY_TYPE",
168: "BOX_TYPE",
171: "FIXED_ARRAY_TYPE",
147: "FIXED_DOUBLE_ARRAY_TYPE",
171: "SHARED_FUNCTION_INFO_TYPE",
172: "JS_MESSAGE_OBJECT_TYPE",
175: "JS_VALUE_TYPE",
176: "JS_DATE_TYPE",
177: "JS_OBJECT_TYPE",
178: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
179: "JS_GENERATOR_OBJECT_TYPE",
180: "JS_MODULE_TYPE",
181: "JS_GLOBAL_OBJECT_TYPE",
182: "JS_BUILTINS_OBJECT_TYPE",
183: "JS_GLOBAL_PROXY_TYPE",
184: "JS_ARRAY_TYPE",
185: "JS_ARRAY_BUFFER_TYPE",
186: "JS_TYPED_ARRAY_TYPE",
187: "JS_DATA_VIEW_TYPE",
174: "JS_PROXY_TYPE",
188: "JS_SET_TYPE",
189: "JS_MAP_TYPE",
190: "JS_WEAK_MAP_TYPE",
191: "JS_WEAK_SET_TYPE",
192: "JS_REGEXP_TYPE",
193: "JS_FUNCTION_TYPE",
173: "JS_FUNCTION_PROXY_TYPE",
168: "DEBUG_INFO_TYPE",
169: "BREAK_POINT_INFO_TYPE",
148: "CONSTANT_POOL_ARRAY_TYPE",
172: "SHARED_FUNCTION_INFO_TYPE",
173: "JS_MESSAGE_OBJECT_TYPE",
176: "JS_VALUE_TYPE",
177: "JS_DATE_TYPE",
178: "JS_OBJECT_TYPE",
179: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
180: "JS_GENERATOR_OBJECT_TYPE",
181: "JS_MODULE_TYPE",
182: "JS_GLOBAL_OBJECT_TYPE",
183: "JS_BUILTINS_OBJECT_TYPE",
184: "JS_GLOBAL_PROXY_TYPE",
185: "JS_ARRAY_TYPE",
186: "JS_ARRAY_BUFFER_TYPE",
187: "JS_TYPED_ARRAY_TYPE",
188: "JS_DATA_VIEW_TYPE",
175: "JS_PROXY_TYPE",
189: "JS_SET_TYPE",
190: "JS_MAP_TYPE",
191: "JS_WEAK_MAP_TYPE",
192: "JS_WEAK_SET_TYPE",
193: "JS_REGEXP_TYPE",
194: "JS_FUNCTION_TYPE",
174: "JS_FUNCTION_PROXY_TYPE",
169: "DEBUG_INFO_TYPE",
170: "BREAK_POINT_INFO_TYPE",
}
# List of known V8 maps.
......@@ -126,85 +127,86 @@ KNOWN_MAPS = {
0x080a9: (129, "MetaMap"),
0x080d1: (131, "OddballMap"),
0x080f9: (4, "AsciiInternalizedStringMap"),
0x08121: (170, "FixedArrayMap"),
0x08121: (171, "FixedArrayMap"),
0x08149: (134, "HeapNumberMap"),
0x08171: (137, "FreeSpaceMap"),
0x08199: (148, "OnePointerFillerMap"),
0x081c1: (148, "TwoPointerFillerMap"),
0x08199: (149, "OnePointerFillerMap"),
0x081c1: (149, "TwoPointerFillerMap"),
0x081e9: (132, "CellMap"),
0x08211: (133, "GlobalPropertyCellMap"),
0x08239: (171, "SharedFunctionInfoMap"),
0x08261: (170, "NativeContextMap"),
0x08239: (172, "SharedFunctionInfoMap"),
0x08261: (171, "NativeContextMap"),
0x08289: (130, "CodeMap"),
0x082b1: (170, "ScopeInfoMap"),
0x082d9: (170, "FixedCOWArrayMap"),
0x082b1: (171, "ScopeInfoMap"),
0x082d9: (171, "FixedCOWArrayMap"),
0x08301: (147, "FixedDoubleArrayMap"),
0x08329: (170, "HashTableMap"),
0x08351: (128, "SymbolMap"),
0x08379: (64, "StringMap"),
0x083a1: (68, "AsciiStringMap"),
0x083c9: (65, "ConsStringMap"),
0x083f1: (69, "ConsAsciiStringMap"),
0x08419: (67, "SlicedStringMap"),
0x08441: (71, "SlicedAsciiStringMap"),
0x08469: (66, "ExternalStringMap"),
0x08491: (74, "ExternalStringWithOneByteDataMap"),
0x084b9: (70, "ExternalAsciiStringMap"),
0x084e1: (82, "ShortExternalStringMap"),
0x08509: (90, "ShortExternalStringWithOneByteDataMap"),
0x08531: (0, "InternalizedStringMap"),
0x08559: (1, "ConsInternalizedStringMap"),
0x08581: (5, "ConsAsciiInternalizedStringMap"),
0x085a9: (2, "ExternalInternalizedStringMap"),
0x085d1: (10, "ExternalInternalizedStringWithOneByteDataMap"),
0x085f9: (6, "ExternalAsciiInternalizedStringMap"),
0x08621: (18, "ShortExternalInternalizedStringMap"),
0x08649: (26, "ShortExternalInternalizedStringWithOneByteDataMap"),
0x08671: (22, "ShortExternalAsciiInternalizedStringMap"),
0x08699: (86, "ShortExternalAsciiStringMap"),
0x086c1: (64, "UndetectableStringMap"),
0x086e9: (68, "UndetectableAsciiStringMap"),
0x08711: (138, "ExternalByteArrayMap"),
0x08739: (139, "ExternalUnsignedByteArrayMap"),
0x08761: (140, "ExternalShortArrayMap"),
0x08789: (141, "ExternalUnsignedShortArrayMap"),
0x087b1: (142, "ExternalIntArrayMap"),
0x087d9: (143, "ExternalUnsignedIntArrayMap"),
0x08801: (144, "ExternalFloatArrayMap"),
0x08829: (145, "ExternalDoubleArrayMap"),
0x08851: (146, "ExternalPixelArrayMap"),
0x08879: (170, "NonStrictArgumentsElementsMap"),
0x088a1: (170, "FunctionContextMap"),
0x088c9: (170, "CatchContextMap"),
0x088f1: (170, "WithContextMap"),
0x08919: (170, "BlockContextMap"),
0x08941: (170, "ModuleContextMap"),
0x08969: (170, "GlobalContextMap"),
0x08991: (172, "JSMessageObjectMap"),
0x089b9: (135, "ForeignMap"),
0x089e1: (177, "NeanderMap"),
0x08a09: (161, "AllocationMementoMap"),
0x08a31: (160, "AllocationSiteMap"),
0x08a59: (164, "PolymorphicCodeCacheMap"),
0x08a81: (162, "ScriptMap"),
0x08ad1: (177, "ExternalMap"),
0x08af9: (167, "BoxMap"),
0x08b21: (149, "DeclaredAccessorDescriptorMap"),
0x08b49: (150, "DeclaredAccessorInfoMap"),
0x08b71: (151, "ExecutableAccessorInfoMap"),
0x08b99: (152, "AccessorPairMap"),
0x08bc1: (153, "AccessCheckInfoMap"),
0x08be9: (154, "InterceptorInfoMap"),
0x08c11: (155, "CallHandlerInfoMap"),
0x08c39: (156, "FunctionTemplateInfoMap"),
0x08c61: (157, "ObjectTemplateInfoMap"),
0x08c89: (158, "SignatureInfoMap"),
0x08cb1: (159, "TypeSwitchInfoMap"),
0x08cd9: (163, "CodeCacheMap"),
0x08d01: (165, "TypeFeedbackInfoMap"),
0x08d29: (166, "AliasedArgumentsEntryMap"),
0x08d51: (168, "DebugInfoMap"),
0x08d79: (169, "BreakPointInfoMap"),
0x08329: (148, "ConstantPoolArrayMap"),
0x08351: (171, "HashTableMap"),
0x08379: (128, "SymbolMap"),
0x083a1: (64, "StringMap"),
0x083c9: (68, "AsciiStringMap"),
0x083f1: (65, "ConsStringMap"),
0x08419: (69, "ConsAsciiStringMap"),
0x08441: (67, "SlicedStringMap"),
0x08469: (71, "SlicedAsciiStringMap"),
0x08491: (66, "ExternalStringMap"),
0x084b9: (74, "ExternalStringWithOneByteDataMap"),
0x084e1: (70, "ExternalAsciiStringMap"),
0x08509: (82, "ShortExternalStringMap"),
0x08531: (90, "ShortExternalStringWithOneByteDataMap"),
0x08559: (0, "InternalizedStringMap"),
0x08581: (1, "ConsInternalizedStringMap"),
0x085a9: (5, "ConsAsciiInternalizedStringMap"),
0x085d1: (2, "ExternalInternalizedStringMap"),
0x085f9: (10, "ExternalInternalizedStringWithOneByteDataMap"),
0x08621: (6, "ExternalAsciiInternalizedStringMap"),
0x08649: (18, "ShortExternalInternalizedStringMap"),
0x08671: (26, "ShortExternalInternalizedStringWithOneByteDataMap"),
0x08699: (22, "ShortExternalAsciiInternalizedStringMap"),
0x086c1: (86, "ShortExternalAsciiStringMap"),
0x086e9: (64, "UndetectableStringMap"),
0x08711: (68, "UndetectableAsciiStringMap"),
0x08739: (138, "ExternalByteArrayMap"),
0x08761: (139, "ExternalUnsignedByteArrayMap"),
0x08789: (140, "ExternalShortArrayMap"),
0x087b1: (141, "ExternalUnsignedShortArrayMap"),
0x087d9: (142, "ExternalIntArrayMap"),
0x08801: (143, "ExternalUnsignedIntArrayMap"),
0x08829: (144, "ExternalFloatArrayMap"),
0x08851: (145, "ExternalDoubleArrayMap"),
0x08879: (146, "ExternalPixelArrayMap"),
0x088a1: (171, "NonStrictArgumentsElementsMap"),
0x088c9: (171, "FunctionContextMap"),
0x088f1: (171, "CatchContextMap"),
0x08919: (171, "WithContextMap"),
0x08941: (171, "BlockContextMap"),
0x08969: (171, "ModuleContextMap"),
0x08991: (171, "GlobalContextMap"),
0x089b9: (173, "JSMessageObjectMap"),
0x089e1: (135, "ForeignMap"),
0x08a09: (178, "NeanderMap"),
0x08a31: (162, "AllocationMementoMap"),
0x08a59: (161, "AllocationSiteMap"),
0x08a81: (165, "PolymorphicCodeCacheMap"),
0x08aa9: (163, "ScriptMap"),
0x08af9: (178, "ExternalMap"),
0x08b21: (168, "BoxMap"),
0x08b49: (150, "DeclaredAccessorDescriptorMap"),
0x08b71: (151, "DeclaredAccessorInfoMap"),
0x08b99: (152, "ExecutableAccessorInfoMap"),
0x08bc1: (153, "AccessorPairMap"),
0x08be9: (154, "AccessCheckInfoMap"),
0x08c11: (155, "InterceptorInfoMap"),
0x08c39: (156, "CallHandlerInfoMap"),
0x08c61: (157, "FunctionTemplateInfoMap"),
0x08c89: (158, "ObjectTemplateInfoMap"),
0x08cb1: (159, "SignatureInfoMap"),
0x08cd9: (160, "TypeSwitchInfoMap"),
0x08d01: (164, "CodeCacheMap"),
0x08d29: (166, "TypeFeedbackInfoMap"),
0x08d51: (167, "AliasedArgumentsEntryMap"),
0x08d79: (169, "DebugInfoMap"),
0x08da1: (170, "BreakPointInfoMap"),
}
# List of known V8 objects.
......@@ -250,6 +252,6 @@ KNOWN_OBJECTS = {
("OLD_DATA_SPACE", 0x082c9): "EmptyExternalPixelArray",
("OLD_DATA_SPACE", 0x082d5): "InfinityValue",
("OLD_DATA_SPACE", 0x082e1): "MinusZeroValue",
("CODE_SPACE", 0x11141): "JsConstructEntryCode",
("CODE_SPACE", 0x18da1): "JsEntryCode",
("CODE_SPACE", 0x111a1): "JsConstructEntryCode",
("CODE_SPACE", 0x18bc1): "JsEntryCode",
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment