Hide heap methods where possible.

Factory is already a friend class of Heap.
We introduce a TestHeap class in cctest.h to access protected methods.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/247263003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21053 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2014-04-29 13:58:55 +00:00
parent c8e95c411c
commit 30e2802e12
8 changed files with 189 additions and 206 deletions

View File

@ -631,10 +631,9 @@ Handle<Symbol> Factory::NewSymbol() {
Handle<Symbol> Factory::NewPrivateSymbol() {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocatePrivateSymbol(),
Symbol);
Handle<Symbol> symbol = NewSymbol();
symbol->set_is_private(true);
return symbol;
}
@ -1333,9 +1332,9 @@ Handle<JSObject> Factory::NewExternal(void* value) {
}
Handle<Code> NewCodeHelper(Isolate* isolate, int object_size, bool immovable) {
CALL_HEAP_FUNCTION(isolate,
isolate->heap()->AllocateCode(object_size, immovable),
Handle<Code> Factory::NewCodeRaw(int object_size, bool immovable) {
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateCode(object_size, immovable),
Code);
}
@ -1354,7 +1353,7 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc,
int body_size = RoundUp(desc.instr_size, kObjectAlignment);
int obj_size = Code::SizeFor(body_size);
Handle<Code> code = NewCodeHelper(isolate(), obj_size, immovable);
Handle<Code> code = NewCodeRaw(obj_size, immovable);
ASSERT(!isolate()->code_range()->exists() ||
isolate()->code_range()->contains(code->address()));

View File

@ -656,6 +656,9 @@ class Factory V8_FINAL {
AllocationSpace space,
Handle<AllocationSite> allocation_site);
// Creates a code object that is not yet fully initialized yet.
inline Handle<Code> NewCodeRaw(int object_size, bool immovable);
// Initializes a function with a shared part and prototype.
// Note: this code was factored out of NewFunction such that other parts of
// the VM could use it. Specifically, a function that creates instances of

View File

@ -4336,15 +4336,6 @@ MaybeObject* Heap::AllocateSymbol() {
}
MaybeObject* Heap::AllocatePrivateSymbol() {
MaybeObject* maybe = AllocateSymbol();
Symbol* symbol;
if (!maybe->To(&symbol)) return maybe;
symbol->set_is_private(true);
return symbol;
}
MaybeObject* Heap::AllocateStruct(InstanceType type) {
Map* map;
switch (type) {

View File

@ -682,18 +682,6 @@ class Heap {
return old_data_space_->allocation_limit_address();
}
// Allocates and initializes a new JavaScript object based on a
// constructor.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// If allocation_site is non-null, then a memento is emitted after the object
// that points to the site.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateJSObject(
JSFunction* constructor,
PretenureFlag pretenure = NOT_TENURED,
AllocationSite* allocation_site = NULL);
// Returns a deep copy of the JavaScript object.
// Properties and elements are copied too.
// Returns failure if allocation failed.
@ -701,44 +689,6 @@ class Heap {
MUST_USE_RESULT MaybeObject* CopyJSObject(JSObject* source,
AllocationSite* site = NULL);
// Allocates and initializes a new JavaScript object based on a map.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Passing an allocation site means that a memento will be created that
// points to the site.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateJSObjectFromMap(
Map* map,
PretenureFlag pretenure = NOT_TENURED,
bool alloc_props = true,
AllocationSite* allocation_site = NULL);
// Allocates a heap object based on the map.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this function does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* Allocate(Map* map, AllocationSpace space,
AllocationSite* allocation_site = NULL);
// Allocates a JS Map in the heap.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this function does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateMap(
InstanceType instance_type,
int instance_size,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);
// Allocates a partial map for bootstrapping.
MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType instance_type,
int instance_size);
// Allocate a block of memory in the given space (filled with a filler).
// Used as a fall-back for generated code when the space is full.
MUST_USE_RESULT MaybeObject* AllocateFillerObject(int size,
bool double_align,
AllocationSpace space);
// Clear the Instanceof cache (used when a prototype changes).
inline void ClearInstanceofCache();
@ -748,32 +698,6 @@ class Heap {
// For use during bootup.
void RepairFreeListsAfterBoot();
// Allocates and fully initializes a String. There are two String
// encodings: ASCII and two byte. One should choose between the three string
// allocation functions based on the encoding of the string buffer used to
// initialized the string.
// - ...FromAscii initializes the string from a buffer that is ASCII
// encoded (it does not check that the buffer is ASCII encoded) and the
// result will be ASCII encoded.
// - ...FromUTF8 initializes the string from a buffer that is UTF-8
// encoded. If the characters are all single-byte characters, the
// result will be ASCII encoded, otherwise it will converted to two
// byte.
// - ...FromTwoByte initializes the string from a buffer that is two-byte
// encoded. If the characters are all single-byte characters, the
// result will be converted to ASCII, otherwise it will be left as
// two-byte.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateStringFromUtf8Slow(
Vector<const char> str,
int non_ascii_start,
PretenureFlag pretenure = NOT_TENURED);
MUST_USE_RESULT MaybeObject* AllocateStringFromTwoByte(
Vector<const uc16> str,
PretenureFlag pretenure = NOT_TENURED);
// Allocates an internalized string in old space based on the character
// stream. Returns Failure::RetryAfterGC(requested_bytes, space) if the
// allocation failed.
@ -798,44 +722,6 @@ class Heap {
MUST_USE_RESULT inline MaybeObject* AllocateInternalizedStringImpl(
T t, int chars, uint32_t hash_field);
template<bool is_one_byte, typename T>
MUST_USE_RESULT MaybeObject* AllocateInternalizedStringImpl(
T t, int chars, uint32_t hash_field);
// Allocate a byte array of the specified length
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateByteArray(
int length,
PretenureFlag pretenure = NOT_TENURED);
// Allocates an external array of the specified length and type.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateExternalArray(
int length,
ExternalArrayType array_type,
void* external_pointer,
PretenureFlag pretenure);
// Allocates a fixed typed array of the specified length and type.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateFixedTypedArray(
int length,
ExternalArrayType array_type,
PretenureFlag pretenure);
// Allocate a symbol in old space.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateSymbol();
MUST_USE_RESULT MaybeObject* AllocatePrivateSymbol();
// Allocates a fixed array initialized with undefined values
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
@ -859,10 +745,6 @@ class Heap {
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
MUST_USE_RESULT inline MaybeObject* CopyFixedArray(FixedArray* src);
// Make a copy of src and return it. Returns
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
MUST_USE_RESULT MaybeObject* CopyAndTenureFixedCOWArray(FixedArray* 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* CopyFixedArrayWithMap(FixedArray* src, Map* map);
@ -872,42 +754,16 @@ class Heap {
MUST_USE_RESULT inline MaybeObject* CopyFixedDoubleArray(
FixedDoubleArray* 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* 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);
MUST_USE_RESULT MaybeObject* AllocateConstantPoolArray(
int number_of_int64_entries,
int number_of_code_ptr_entries,
int number_of_heap_ptr_entries,
int number_of_int32_entries);
// 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.
MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedDoubleArray(
int length,
PretenureFlag pretenure = NOT_TENURED);
// AllocateHashTable is identical to AllocateFixedArray except
// that the resulting object has hash_table_map as map.
MUST_USE_RESULT MaybeObject* AllocateHashTable(
int length, PretenureFlag pretenure = NOT_TENURED);
// Allocates a new utility object in the old generation.
MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
// Sloppy mode arguments object size.
static const int kSloppyArgumentsObjectSize =
JSObject::kHeaderSize + 2 * kPointerSize;
@ -919,17 +775,6 @@ class Heap {
// callee is only valid in sloppy mode.
static const int kArgumentsCalleeIndex = 1;
// Allocates an arguments object - optionally with an elements array.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateArgumentsObject(
Object* callee, int length);
// Allocated a HeapNumber from value.
MUST_USE_RESULT MaybeObject* AllocateHeapNumber(
double value, PretenureFlag pretenure = NOT_TENURED);
// Converts an int into either a Smi or a HeapNumber object.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
@ -937,13 +782,6 @@ class Heap {
MUST_USE_RESULT inline MaybeObject* NumberFromUint32(
uint32_t value, PretenureFlag pretenure = NOT_TENURED);
// Allocates a new foreign object.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateForeign(
Address address, PretenureFlag pretenure = NOT_TENURED);
// Finalizes an external string by deleting the associated external
// data and clearing the resource pointer.
inline void FinalizeExternalString(String* string);
@ -959,21 +797,6 @@ class Heap {
// Maintain marking consistency for IncrementalMarking.
void AdjustLiveBytes(Address address, int by, InvocationMode mode);
MUST_USE_RESULT MaybeObject* AllocateCode(int object_size, bool immovable);
MUST_USE_RESULT MaybeObject* CopyCode(Code* code);
// Copy the code and scope info part of the code object, but insert
// the provided data as the relocation information.
MUST_USE_RESULT MaybeObject* CopyCode(Code* code, Vector<byte> reloc_info);
// Finds the internalized copy for string in the string table.
// If not found, a new string is added to the table and returned.
// Returns Failure::RetryAfterGC(requested_bytes, space) if allocation
// failed.
// Please note this function does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* InternalizeStringWithKey(HashTableKey* key);
bool InternalizeStringIfExists(String* str, String** result);
bool InternalizeTwoCharsStringIfExists(String* str, String** result);
@ -1673,6 +1496,52 @@ class Heap {
static void FatalProcessOutOfMemory(const char* location,
bool take_snapshot = false);
protected:
// Methods made available to tests.
// Allocates a JS Map in the heap.
MUST_USE_RESULT MaybeObject* AllocateMap(
InstanceType instance_type,
int instance_size,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);
// Allocates and initializes a new JavaScript object based on a
// constructor.
// If allocation_site is non-null, then a memento is emitted after the object
// that points to the site.
MUST_USE_RESULT MaybeObject* AllocateJSObject(
JSFunction* constructor,
PretenureFlag pretenure = NOT_TENURED,
AllocationSite* allocation_site = NULL);
// Allocates and initializes a new JavaScript object based on a map.
// Passing an allocation site means that a memento will be created that
// points to the site.
MUST_USE_RESULT MaybeObject* AllocateJSObjectFromMap(
Map* map,
PretenureFlag pretenure = NOT_TENURED,
bool alloc_props = true,
AllocationSite* allocation_site = NULL);
// Allocated a HeapNumber from value.
MUST_USE_RESULT MaybeObject* AllocateHeapNumber(
double value, PretenureFlag pretenure = NOT_TENURED);
// Allocate a byte array of the specified length
MUST_USE_RESULT MaybeObject* AllocateByteArray(
int length,
PretenureFlag pretenure = NOT_TENURED);
// Allocates an arguments object - optionally with an elements array.
MUST_USE_RESULT MaybeObject* AllocateArgumentsObject(
Object* callee, int length);
// Copy the code and scope info part of the code object, but insert
// the provided data as the relocation information.
MUST_USE_RESULT MaybeObject* CopyCode(Code* code, Vector<byte> reloc_info);
MUST_USE_RESULT MaybeObject* CopyCode(Code* code);
private:
Heap();
@ -1929,6 +1798,27 @@ class Heap {
AllocationSpace space,
AllocationSpace retry_space);
// Allocates a heap object based on the map.
MUST_USE_RESULT MaybeObject* Allocate(Map* map, AllocationSpace space,
AllocationSite* allocation_site = NULL);
// Allocates a partial map for bootstrapping.
MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType instance_type,
int instance_size);
// Initializes a JSObject based on its map.
void InitializeJSObjectFromMap(JSObject* obj,
FixedArray* properties,
Map* map);
void InitializeAllocationMemento(AllocationMemento* memento,
AllocationSite* allocation_site);
// Allocate a block of memory in the given space (filled with a filler).
// Used as a fall-back for generated code when the space is full.
MUST_USE_RESULT MaybeObject* AllocateFillerObject(int size,
bool double_align,
AllocationSpace space);
// Allocate an uninitialized fixed array.
MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(
int length, PretenureFlag pretenure);
@ -1950,16 +1840,79 @@ class Heap {
MUST_USE_RESULT MaybeObject* AllocateRawTwoByteString(
int length, PretenureFlag pretenure);
// Initializes a JSObject based on its map.
void InitializeJSObjectFromMap(JSObject* obj,
FixedArray* properties,
Map* map);
void InitializeAllocationMemento(AllocationMemento* memento,
AllocationSite* allocation_site);
// Allocates and fully initializes a String. There are two String
// encodings: ASCII and two byte. One should choose between the three string
// allocation functions based on the encoding of the string buffer used to
// initialized the string.
// - ...FromAscii initializes the string from a buffer that is ASCII
// encoded (it does not check that the buffer is ASCII encoded) and the
// result will be ASCII encoded.
// - ...FromUTF8 initializes the string from a buffer that is UTF-8
// encoded. If the characters are all single-byte characters, the
// result will be ASCII encoded, otherwise it will converted to two
// byte.
// - ...FromTwoByte initializes the string from a buffer that is two-byte
// encoded. If the characters are all single-byte characters, the
// result will be converted to ASCII, otherwise it will be left as
// two-byte.
MUST_USE_RESULT MaybeObject* AllocateStringFromUtf8Slow(
Vector<const char> str,
int non_ascii_start,
PretenureFlag pretenure = NOT_TENURED);
MUST_USE_RESULT MaybeObject* AllocateStringFromTwoByte(
Vector<const uc16> str,
PretenureFlag pretenure = NOT_TENURED);
bool CreateInitialMaps();
void CreateInitialObjects();
template<bool is_one_byte, typename T>
MUST_USE_RESULT MaybeObject* AllocateInternalizedStringImpl(
T t, int chars, uint32_t hash_field);
// Computes a single character string where the character has code.
// A cache is used for ASCII codes.
MUST_USE_RESULT MaybeObject* LookupSingleCharacterStringFromCode(
uint16_t code);
// Allocate a symbol in old space.
MUST_USE_RESULT MaybeObject* AllocateSymbol();
// Make a copy of src, set the map, and return the copy.
MUST_USE_RESULT MaybeObject* CopyConstantPoolArrayWithMap(
ConstantPoolArray* src, Map* map);
MUST_USE_RESULT MaybeObject* AllocateConstantPoolArray(
int number_of_int64_entries,
int number_of_code_ptr_entries,
int number_of_heap_ptr_entries,
int number_of_int32_entries);
// Allocates an external array of the specified length and type.
MUST_USE_RESULT MaybeObject* AllocateExternalArray(
int length,
ExternalArrayType array_type,
void* external_pointer,
PretenureFlag pretenure);
// Allocates a fixed typed array of the specified length and type.
MUST_USE_RESULT MaybeObject* AllocateFixedTypedArray(
int length,
ExternalArrayType array_type,
PretenureFlag pretenure);
// Make a copy of src and return it.
MUST_USE_RESULT MaybeObject* CopyAndTenureFixedCOWArray(FixedArray* src);
// Make a copy of src, set the map, and return the copy.
MUST_USE_RESULT MaybeObject* CopyFixedDoubleArrayWithMap(
FixedDoubleArray* src, Map* map);
// Allocates a fixed double array with uninitialized values. Returns
MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedDoubleArray(
int length,
PretenureFlag pretenure = NOT_TENURED);
// These five Create*EntryStub functions are here and forced to not be inlined
// because of a gcc-4.4 bug that assigns wrong vtable entries.
NO_INLINE(void CreateJSEntryStub());
@ -1987,6 +1940,19 @@ class Heap {
// Allocate a tenured JS global property cell initialized with the hole.
MUST_USE_RESULT MaybeObject* AllocatePropertyCell();
// Allocates a new utility object in the old generation.
MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
// Allocates a new foreign object.
MUST_USE_RESULT MaybeObject* AllocateForeign(
Address address, PretenureFlag pretenure = NOT_TENURED);
MUST_USE_RESULT MaybeObject* AllocateCode(int object_size, bool immovable);
MUST_USE_RESULT MaybeObject* InternalizeStringWithKey(HashTableKey* key);
MUST_USE_RESULT MaybeObject* InternalizeString(String* str);
// Performs a minor collection in new generation.
void Scavenge();

View File

@ -80,6 +80,19 @@ typedef v8::internal::EnumSet<CcTestExtensionIds> CcTestExtensionFlags;
#undef DEFINE_EXTENSION_FLAG
// Use this to expose protected methods in i::Heap.
class TestHeap : public i::Heap {
public:
using i::Heap::AllocateHeapNumber;
using i::Heap::AllocateMap;
using i::Heap::AllocateJSObject;
using i::Heap::AllocateJSObjectFromMap;
using i::Heap::AllocateByteArray;
using i::Heap::AllocateArgumentsObject;
using i::Heap::CopyCode;
};
class CcTest {
public:
typedef void (TestFunction)();
@ -107,6 +120,10 @@ class CcTest {
return i_isolate()->heap();
}
static TestHeap* test_heap() {
return reinterpret_cast<TestHeap*>(i_isolate()->heap());
}
static v8::Local<v8::Object> global() {
return isolate()->GetCurrentContext()->Global();
}

View File

@ -38,7 +38,7 @@ using namespace v8::internal;
static MaybeObject* AllocateAfterFailures() {
static int attempts = 0;
if (++attempts < 3) return Failure::RetryAfterGC();
Heap* heap = CcTest::heap();
TestHeap* heap = CcTest::test_heap();
// New space.
SimulateFullSpace(heap->new_space());

View File

@ -595,13 +595,20 @@ static const char* not_so_random_string_table[] = {
static void CheckInternalizedStrings(const char** strings) {
Factory* factory = CcTest::i_isolate()->factory();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
for (const char* string = *strings; *strings != 0; string = *strings++) {
Handle<String> a = factory->InternalizeUtf8String(string);
HandleScope scope(isolate);
Handle<String> a =
isolate->factory()->InternalizeUtf8String(CStrVector(string));
// InternalizeUtf8String may return a failure if a GC is needed.
CHECK(a->IsInternalizedString());
Handle<String> b = factory->InternalizeUtf8String(string);
CHECK_EQ(*b, *a);
CHECK(String::cast(*b)->IsUtf8EqualTo(CStrVector(string)));
CHECK(b->IsUtf8EqualTo(CStrVector(string)));
b = isolate->factory()->InternalizeUtf8String(CStrVector(string));
CHECK_EQ(*b, *a);
CHECK(b->IsUtf8EqualTo(CStrVector(string)));
}
}
@ -977,7 +984,7 @@ TEST(Regression39128) {
// Test case for crbug.com/39128.
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
TestHeap* heap = CcTest::test_heap();
// Increase the chance of 'bump-the-pointer' allocation in old space.
heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);

View File

@ -128,7 +128,7 @@ TEST(MarkCompactCollector) {
FLAG_incremental_marking = false;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
TestHeap* heap = CcTest::test_heap();
Factory* factory = isolate->factory();
v8::HandleScope sc(CcTest::isolate());