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);
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment