From 98db16d94ffd493b06bf34c30f8863c1afaf2fee Mon Sep 17 00:00:00 2001 From: "sanjoy@chromium.org" Date: Mon, 4 Jun 2012 14:42:58 +0000 Subject: [PATCH] Progress towards making Zones independent of Isolates and Threads. This CL changes some parts of the code to explicitly pass around a Zone. Not passing in a zone is okay too (in fact most of v8 still doesn't), but that may incur a TLS lookup. BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/10443114 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11709 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/allocation-inl.h | 4 +- src/allocation.h | 14 ++--- src/arm/lithium-arm.cc | 3 +- src/arm/lithium-arm.h | 2 +- src/arm/lithium-codegen-arm.cc | 5 +- src/arm/lithium-codegen-arm.h | 11 +++- src/ast.h | 4 +- src/compiler.cc | 2 +- src/deoptimizer.cc | 56 ++++++++++---------- src/deoptimizer.h | 19 ++++--- src/full-codegen.h | 7 ++- src/hashmap.h | 87 +++++++++++++++++++------------- src/hydrogen.cc | 4 +- src/hydrogen.h | 2 +- src/ia32/lithium-codegen-ia32.cc | 5 +- src/ia32/lithium-codegen-ia32.h | 11 +++- src/ia32/lithium-ia32.cc | 3 +- src/ia32/lithium-ia32.h | 2 +- src/isolate.cc | 2 +- src/isolate.h | 2 +- src/jsregexp.cc | 86 ++++++++++++++++++------------- src/jsregexp.h | 67 +++++++++++++++--------- src/list-inl.h | 40 +++++++-------- src/list.h | 57 ++++++++++++++------- src/lithium.h | 10 +++- src/parser.cc | 55 +++++++++++--------- src/parser.h | 13 +++-- src/runtime.cc | 36 ++++++++----- src/safepoint-table.h | 17 ++++--- src/splay-tree-inl.h | 17 ++++--- src/splay-tree.h | 25 +++++---- src/string-stream.cc | 2 +- src/v8.h | 1 + src/x64/lithium-codegen-x64.cc | 7 +-- src/x64/lithium-codegen-x64.h | 11 +++- src/x64/lithium-x64.cc | 3 +- src/x64/lithium-x64.h | 2 +- src/zone-inl.h | 11 ++-- src/zone.h | 69 +++++++++++++++++-------- test/cctest/test-list.cc | 2 +- test/cctest/test-parsing.cc | 5 +- test/cctest/test-regexp.cc | 3 +- 42 files changed, 479 insertions(+), 305 deletions(-) diff --git a/src/allocation-inl.h b/src/allocation-inl.h index 04a3fe667..d32db4b17 100644 --- a/src/allocation-inl.h +++ b/src/allocation-inl.h @@ -34,12 +34,12 @@ namespace v8 { namespace internal { -void* PreallocatedStorage::New(size_t size) { +void* PreallocatedStorageAllocationPolicy::New(size_t size) { return Isolate::Current()->PreallocatedStorageNew(size); } -void PreallocatedStorage::Delete(void* p) { +void PreallocatedStorageAllocationPolicy::Delete(void* p) { return Isolate::Current()->PreallocatedStorageDelete(p); } diff --git a/src/allocation.h b/src/allocation.h index 31067dda8..45bde4c4c 100644 --- a/src/allocation.h +++ b/src/allocation.h @@ -104,7 +104,7 @@ char* StrNDup(const char* str, int n); // and free. Used as the default policy for lists. class FreeStoreAllocationPolicy { public: - INLINE(static void* New(size_t size)) { return Malloced::New(size); } + INLINE(void* New(size_t size)) { return Malloced::New(size); } INLINE(static void Delete(void* p)) { Malloced::Delete(p); } }; @@ -117,12 +117,6 @@ class PreallocatedStorage { explicit PreallocatedStorage(size_t size); size_t size() { return size_; } - // TODO(isolates): Get rid of these-- we'll have to change the allocator - // interface to include a pointer to an isolate to do this - // efficiently. - static inline void* New(size_t size); - static inline void Delete(void* p); - private: size_t size_; PreallocatedStorage* previous_; @@ -137,6 +131,12 @@ class PreallocatedStorage { }; +struct PreallocatedStorageAllocationPolicy { + INLINE(void* New(size_t size)); + INLINE(static void Delete(void* ptr)); +}; + + } } // namespace v8::internal #endif // V8_ALLOCATION_H_ diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 7618e3dd4..0f0545355 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -985,7 +985,8 @@ LEnvironment* LChunkBuilder::CreateEnvironment( hydrogen_env->parameter_count(), argument_count_, value_count, - outer); + outer, + zone()); int argument_index = *argument_index_accumulator; for (int i = 0; i < value_count; ++i) { if (hydrogen_env->is_special_index(i)) continue; diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 735914f44..39894a48c 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -2286,7 +2286,7 @@ class LChunkBuilder BASE_EMBEDDED { : chunk_(NULL), info_(info), graph_(graph), - zone_(graph->isolate()->zone()), + zone_(graph->zone()), status_(UNUSED), current_instruction_(NULL), current_block_(NULL), diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index a360334df..1d87c6adb 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -631,7 +631,8 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, ++jsframe_count; } } - Translation translation(&translations_, frame_count, jsframe_count); + Translation translation(&translations_, frame_count, jsframe_count, + zone()); WriteTranslation(environment, &translation); int deoptimization_index = deoptimizations_.length(); int pc_offset = masm()->pc_offset(); @@ -761,7 +762,7 @@ void LCodeGen::RecordSafepoint( for (int i = 0; i < operands->length(); i++) { LOperand* pointer = operands->at(i); if (pointer->IsStackSlot()) { - safepoint.DefinePointerSlot(pointer->index()); + safepoint.DefinePointerSlot(pointer->index(), zone()); } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { safepoint.DefinePointerRegister(ToRegister(pointer)); } diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h index c6a3af7e0..17fd09fa9 100644 --- a/src/arm/lithium-codegen-arm.h +++ b/src/arm/lithium-codegen-arm.h @@ -43,7 +43,8 @@ class SafepointGenerator; class LCodeGen BASE_EMBEDDED { public: - LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) + LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info, + Zone* zone) : chunk_(chunk), masm_(assembler), info_(info), @@ -56,11 +57,14 @@ class LCodeGen BASE_EMBEDDED { inlined_function_count_(0), scope_(info->scope()), status_(UNUSED), + translations_(zone), deferred_(8), osr_pc_offset_(-1), last_lazy_deopt_pc_(0), + safepoints_(zone), resolver_(this), - expected_safepoint_kind_(Safepoint::kSimple) { + expected_safepoint_kind_(Safepoint::kSimple), + zone_(zone) { PopulateDeoptimizationLiteralsWithInlinedFunctions(); } @@ -71,6 +75,7 @@ class LCodeGen BASE_EMBEDDED { Isolate* isolate() const { return info_->isolate(); } Factory* factory() const { return isolate()->factory(); } Heap* heap() const { return isolate()->heap(); } + Zone* zone() const { return zone_; } // Support for converting LOperands to assembler types. // LOperand must be a register. @@ -371,6 +376,8 @@ class LCodeGen BASE_EMBEDDED { Safepoint::Kind expected_safepoint_kind_; + Zone* zone_; + class PushSafepointRegistersScope BASE_EMBEDDED { public: PushSafepointRegistersScope(LCodeGen* codegen, diff --git a/src/ast.h b/src/ast.h index dad80576b..6417d9f3c 100644 --- a/src/ast.h +++ b/src/ast.h @@ -416,7 +416,9 @@ class Block: public BreakableStatement { public: DECLARE_NODE_TYPE(Block) - void AddStatement(Statement* statement) { statements_.Add(statement); } + void AddStatement(Statement* statement, Zone* zone) { + statements_.Add(statement, zone); + } ZoneList* statements() { return &statements_; } bool is_initializer_block() const { return is_initializer_block_; } diff --git a/src/compiler.cc b/src/compiler.cc index ecac5cba6..e8094ed1f 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -304,7 +304,7 @@ static bool MakeCrankshaftCode(CompilationInfo* info) { } if (graph != NULL) { - Handle optimized_code = graph->Compile(info); + Handle optimized_code = graph->Compile(info, graph->zone()); if (!optimized_code.is_null()) { info->SetCode(optimized_code); FinishOptimization(info->closure(), start); diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index 2a30ddd3d..8f411a37e 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -1290,7 +1290,7 @@ Object* FrameDescription::GetExpression(int index) { } -void TranslationBuffer::Add(int32_t value) { +void TranslationBuffer::Add(int32_t value, Zone* zone) { // Encode the sign bit in the least significant bit. bool is_negative = (value < 0); uint32_t bits = ((is_negative ? -value : value) << 1) | @@ -1299,7 +1299,7 @@ void TranslationBuffer::Add(int32_t value) { // each byte to indicate whether or not more bytes follow. do { uint32_t next = bits >> 7; - contents_.Add(((bits << 1) & 0xFF) | (next != 0)); + contents_.Add(((bits << 1) & 0xFF) | (next != 0), zone); bits = next; } while (bits != 0); } @@ -1332,76 +1332,76 @@ Handle TranslationBuffer::CreateByteArray() { void Translation::BeginConstructStubFrame(int literal_id, unsigned height) { - buffer_->Add(CONSTRUCT_STUB_FRAME); - buffer_->Add(literal_id); - buffer_->Add(height); + buffer_->Add(CONSTRUCT_STUB_FRAME, zone()); + buffer_->Add(literal_id, zone()); + buffer_->Add(height, zone()); } void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) { - buffer_->Add(ARGUMENTS_ADAPTOR_FRAME); - buffer_->Add(literal_id); - buffer_->Add(height); + buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone()); + buffer_->Add(literal_id, zone()); + buffer_->Add(height, zone()); } void Translation::BeginJSFrame(int node_id, int literal_id, unsigned height) { - buffer_->Add(JS_FRAME); - buffer_->Add(node_id); - buffer_->Add(literal_id); - buffer_->Add(height); + buffer_->Add(JS_FRAME, zone()); + buffer_->Add(node_id, zone()); + buffer_->Add(literal_id, zone()); + buffer_->Add(height, zone()); } void Translation::StoreRegister(Register reg) { - buffer_->Add(REGISTER); - buffer_->Add(reg.code()); + buffer_->Add(REGISTER, zone()); + buffer_->Add(reg.code(), zone()); } void Translation::StoreInt32Register(Register reg) { - buffer_->Add(INT32_REGISTER); - buffer_->Add(reg.code()); + buffer_->Add(INT32_REGISTER, zone()); + buffer_->Add(reg.code(), zone()); } void Translation::StoreDoubleRegister(DoubleRegister reg) { - buffer_->Add(DOUBLE_REGISTER); - buffer_->Add(DoubleRegister::ToAllocationIndex(reg)); + buffer_->Add(DOUBLE_REGISTER, zone()); + buffer_->Add(DoubleRegister::ToAllocationIndex(reg), zone()); } void Translation::StoreStackSlot(int index) { - buffer_->Add(STACK_SLOT); - buffer_->Add(index); + buffer_->Add(STACK_SLOT, zone()); + buffer_->Add(index, zone()); } void Translation::StoreInt32StackSlot(int index) { - buffer_->Add(INT32_STACK_SLOT); - buffer_->Add(index); + buffer_->Add(INT32_STACK_SLOT, zone()); + buffer_->Add(index, zone()); } void Translation::StoreDoubleStackSlot(int index) { - buffer_->Add(DOUBLE_STACK_SLOT); - buffer_->Add(index); + buffer_->Add(DOUBLE_STACK_SLOT, zone()); + buffer_->Add(index, zone()); } void Translation::StoreLiteral(int literal_id) { - buffer_->Add(LITERAL); - buffer_->Add(literal_id); + buffer_->Add(LITERAL, zone()); + buffer_->Add(literal_id, zone()); } void Translation::StoreArgumentsObject() { - buffer_->Add(ARGUMENTS_OBJECT); + buffer_->Add(ARGUMENTS_OBJECT, zone()); } void Translation::MarkDuplicate() { - buffer_->Add(DUPLICATE); + buffer_->Add(DUPLICATE, zone()); } diff --git a/src/deoptimizer.h b/src/deoptimizer.h index 6bc4a5103..6cf7143c0 100644 --- a/src/deoptimizer.h +++ b/src/deoptimizer.h @@ -515,10 +515,10 @@ class FrameDescription { class TranslationBuffer BASE_EMBEDDED { public: - TranslationBuffer() : contents_(256) { } + explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { } int CurrentIndex() const { return contents_.length(); } - void Add(int32_t value); + void Add(int32_t value, Zone* zone); Handle CreateByteArray(); @@ -569,12 +569,14 @@ class Translation BASE_EMBEDDED { DUPLICATE }; - Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count) + Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count, + Zone* zone) : buffer_(buffer), - index_(buffer->CurrentIndex()) { - buffer_->Add(BEGIN); - buffer_->Add(frame_count); - buffer_->Add(jsframe_count); + index_(buffer->CurrentIndex()), + zone_(zone) { + buffer_->Add(BEGIN, zone); + buffer_->Add(frame_count, zone); + buffer_->Add(jsframe_count, zone); } int index() const { return index_; } @@ -593,6 +595,8 @@ class Translation BASE_EMBEDDED { void StoreArgumentsObject(); void MarkDuplicate(); + Zone* zone() { return zone_; } + static int NumberOfOperandsFor(Opcode opcode); #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) @@ -602,6 +606,7 @@ class Translation BASE_EMBEDDED { private: TranslationBuffer* buffer_; int index_; + Zone* zone_; }; diff --git a/src/full-codegen.h b/src/full-codegen.h index 0e0ffe924..2a6b7057c 100644 --- a/src/full-codegen.h +++ b/src/full-codegen.h @@ -796,12 +796,11 @@ class FullCodeGenerator: public AstVisitor { // A map from property names to getter/setter pairs allocated in the zone. class AccessorTable: public TemplateHashMap { + ZoneAllocationPolicy> { public: explicit AccessorTable(Zone* zone) : - TemplateHashMap(Literal::Match), + TemplateHashMap(Literal::Match), zone_(zone) { } Iterator lookup(Literal* literal) { diff --git a/src/hashmap.h b/src/hashmap.h index 91843b81b..e32ed16cc 100644 --- a/src/hashmap.h +++ b/src/hashmap.h @@ -40,9 +40,16 @@ class TemplateHashMapImpl { public: typedef bool (*MatchFun) (void* key1, void* key2); + // The default capacity. This is used by the call sites which want + // to pass in a non-default AllocationPolicy but want to use the + // default value of capacity specified by the implementation. + static const uint32_t kDefaultHashMapCapacity = 8; + // initial_capacity is the size of the initial hash map; // it must be a power of 2 (and thus must not be 0). - TemplateHashMapImpl(MatchFun match, uint32_t initial_capacity = 8); + TemplateHashMapImpl(MatchFun match, + uint32_t capacity = kDefaultHashMapCapacity, + AllocationPolicy allocator = AllocationPolicy()); ~TemplateHashMapImpl(); @@ -60,7 +67,8 @@ class TemplateHashMapImpl { // but insert is set, a new entry is inserted with // corresponding key, key hash, and NULL value. // Otherwise, NULL is returned. - Entry* Lookup(void* key, uint32_t hash, bool insert); + Entry* Lookup(void* key, uint32_t hash, bool insert, + AllocationPolicy allocator = AllocationPolicy()); // Removes the entry with matching key. // It returns the value of the deleted entry @@ -97,29 +105,30 @@ class TemplateHashMapImpl { Entry* map_end() const { return map_ + capacity_; } Entry* Probe(void* key, uint32_t hash); - void Initialize(uint32_t capacity); - void Resize(); + void Initialize(uint32_t capacity, AllocationPolicy allocator); + void Resize(AllocationPolicy allocator); }; typedef TemplateHashMapImpl HashMap; -template -TemplateHashMapImpl

::TemplateHashMapImpl(MatchFun match, - uint32_t initial_capacity) { +template +TemplateHashMapImpl::TemplateHashMapImpl( + MatchFun match, uint32_t initial_capacity, AllocationPolicy allocator) { match_ = match; - Initialize(initial_capacity); + Initialize(initial_capacity, allocator); } -template -TemplateHashMapImpl

::~TemplateHashMapImpl() { - P::Delete(map_); +template +TemplateHashMapImpl::~TemplateHashMapImpl() { + AllocationPolicy::Delete(map_); } -template -typename TemplateHashMapImpl

::Entry* TemplateHashMapImpl

::Lookup( - void* key, uint32_t hash, bool insert) { +template +typename TemplateHashMapImpl::Entry* +TemplateHashMapImpl::Lookup( + void* key, uint32_t hash, bool insert, AllocationPolicy allocator) { // Find a matching entry. Entry* p = Probe(key, hash); if (p->key != NULL) { @@ -135,7 +144,7 @@ typename TemplateHashMapImpl

::Entry* TemplateHashMapImpl

::Lookup( // Grow the map if we reached >= 80% occupancy. if (occupancy_ + occupancy_/4 >= capacity_) { - Resize(); + Resize(allocator); p = Probe(key, hash); } @@ -147,8 +156,8 @@ typename TemplateHashMapImpl

::Entry* TemplateHashMapImpl

::Lookup( } -template -void* TemplateHashMapImpl

::Remove(void* key, uint32_t hash) { +template +void* TemplateHashMapImpl::Remove(void* key, uint32_t hash) { // Lookup the entry for the key to remove. Entry* p = Probe(key, hash); if (p->key == NULL) { @@ -209,8 +218,8 @@ void* TemplateHashMapImpl

::Remove(void* key, uint32_t hash) { } -template -void TemplateHashMapImpl

::Clear() { +template +void TemplateHashMapImpl::Clear() { // Mark all entries as empty. const Entry* end = map_end(); for (Entry* p = map_; p < end; p++) { @@ -220,15 +229,16 @@ void TemplateHashMapImpl

::Clear() { } -template -typename TemplateHashMapImpl

::Entry* TemplateHashMapImpl

::Start() const { +template +typename TemplateHashMapImpl::Entry* + TemplateHashMapImpl::Start() const { return Next(map_ - 1); } -template -typename TemplateHashMapImpl

::Entry* TemplateHashMapImpl

::Next(Entry* p) - const { +template +typename TemplateHashMapImpl::Entry* + TemplateHashMapImpl::Next(Entry* p) const { const Entry* end = map_end(); ASSERT(map_ - 1 <= p && p < end); for (p++; p < end; p++) { @@ -240,9 +250,9 @@ typename TemplateHashMapImpl

::Entry* TemplateHashMapImpl

::Next(Entry* p) } -template -typename TemplateHashMapImpl

::Entry* TemplateHashMapImpl

::Probe(void* key, - uint32_t hash) { +template +typename TemplateHashMapImpl::Entry* + TemplateHashMapImpl::Probe(void* key, uint32_t hash) { ASSERT(key != NULL); ASSERT(IsPowerOf2(capacity_)); @@ -262,10 +272,11 @@ typename TemplateHashMapImpl

::Entry* TemplateHashMapImpl

::Probe(void* key, } -template -void TemplateHashMapImpl

::Initialize(uint32_t capacity) { +template +void TemplateHashMapImpl::Initialize( + uint32_t capacity, AllocationPolicy allocator) { ASSERT(IsPowerOf2(capacity)); - map_ = reinterpret_cast(P::New(capacity * sizeof(Entry))); + map_ = reinterpret_cast(allocator.New(capacity * sizeof(Entry))); if (map_ == NULL) { v8::internal::FatalProcessOutOfMemory("HashMap::Initialize"); return; @@ -275,13 +286,13 @@ void TemplateHashMapImpl

::Initialize(uint32_t capacity) { } -template -void TemplateHashMapImpl

::Resize() { +template +void TemplateHashMapImpl::Resize(AllocationPolicy allocator) { Entry* map = map_; uint32_t n = occupancy_; // Allocate larger map. - Initialize(capacity_ * 2); + Initialize(capacity_ * 2, allocator); // Rehash all current entries. for (Entry* p = map; n > 0; p++) { @@ -292,7 +303,7 @@ void TemplateHashMapImpl

::Resize() { } // Delete old map. - P::Delete(map); + AllocationPolicy::Delete(map); } @@ -329,8 +340,12 @@ class TemplateHashMap: private TemplateHashMapImpl { }; TemplateHashMap( - typename TemplateHashMapImpl::MatchFun match) - : TemplateHashMapImpl(match) { } + typename TemplateHashMapImpl::MatchFun match, + AllocationPolicy allocator = AllocationPolicy()) + : TemplateHashMapImpl( + match, + TemplateHashMapImpl::kDefaultHashMapCapacity, + allocator) { } Iterator begin() const { return Iterator(this, this->Start()); } Iterator end() const { return Iterator(this, NULL); } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index d880b0283..5dbf2fc9a 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -687,7 +687,7 @@ HGraph::HGraph(CompilationInfo* info) } -Handle HGraph::Compile(CompilationInfo* info) { +Handle HGraph::Compile(CompilationInfo* info, Zone* zone) { int values = GetMaximumValueID(); if (values > LUnallocated::kMaxVirtualRegisters) { if (FLAG_trace_bailout) { @@ -708,7 +708,7 @@ Handle HGraph::Compile(CompilationInfo* info) { } MacroAssembler assembler(info->isolate(), NULL, 0); - LCodeGen generator(chunk, &assembler, info); + LCodeGen generator(chunk, &assembler, info, zone); chunk->MarkEmptyBlocks(); diff --git a/src/hydrogen.h b/src/hydrogen.h index 5c8ddbf6d..82add7abe 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -280,7 +280,7 @@ class HGraph: public ZoneObject { void CollectPhis(); - Handle Compile(CompilationInfo* info); + Handle Compile(CompilationInfo* info, Zone* zone); void set_undefined_constant(HConstant* constant) { undefined_constant_.set(constant); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index ca093ec65..7966e19fe 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -536,7 +536,8 @@ void LCodeGen::RegisterEnvironmentForDeoptimization( ++jsframe_count; } } - Translation translation(&translations_, frame_count, jsframe_count); + Translation translation(&translations_, frame_count, jsframe_count, + zone()); WriteTranslation(environment, &translation); int deoptimization_index = deoptimizations_.length(); int pc_offset = masm()->pc_offset(); @@ -683,7 +684,7 @@ void LCodeGen::RecordSafepoint( for (int i = 0; i < operands->length(); i++) { LOperand* pointer = operands->at(i); if (pointer->IsStackSlot()) { - safepoint.DefinePointerSlot(pointer->index()); + safepoint.DefinePointerSlot(pointer->index(), zone()); } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { safepoint.DefinePointerRegister(ToRegister(pointer)); } diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 392bca2af..28facc515 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -46,7 +46,8 @@ class SafepointGenerator; class LCodeGen BASE_EMBEDDED { public: - LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) + LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info, + Zone* zone) : chunk_(chunk), masm_(assembler), info_(info), @@ -58,11 +59,14 @@ class LCodeGen BASE_EMBEDDED { inlined_function_count_(0), scope_(info->scope()), status_(UNUSED), + translations_(zone), deferred_(8), osr_pc_offset_(-1), last_lazy_deopt_pc_(0), + safepoints_(zone), resolver_(this), - expected_safepoint_kind_(Safepoint::kSimple) { + expected_safepoint_kind_(Safepoint::kSimple), + zone_(zone) { PopulateDeoptimizationLiteralsWithInlinedFunctions(); } @@ -72,6 +76,7 @@ class LCodeGen BASE_EMBEDDED { Isolate* isolate() const { return info_->isolate(); } Factory* factory() const { return isolate()->factory(); } Heap* heap() const { return isolate()->heap(); } + Zone* zone() const { return zone_; } // Support for converting LOperands to assembler types. Operand ToOperand(LOperand* op) const; @@ -349,6 +354,8 @@ class LCodeGen BASE_EMBEDDED { Safepoint::Kind expected_safepoint_kind_; + Zone* zone_; + class PushSafepointRegistersScope BASE_EMBEDDED { public: explicit PushSafepointRegistersScope(LCodeGen* codegen) diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 8f76c5ad3..26af236b4 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -991,7 +991,8 @@ LEnvironment* LChunkBuilder::CreateEnvironment( hydrogen_env->parameter_count(), argument_count_, value_count, - outer); + outer, + zone()); int argument_index = *argument_index_accumulator; for (int i = 0; i < value_count; ++i) { if (hydrogen_env->is_special_index(i)) continue; diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index d7f2993c7..601c9c2f7 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -2373,7 +2373,7 @@ class LChunkBuilder BASE_EMBEDDED { : chunk_(NULL), info_(info), graph_(graph), - zone_(graph->isolate()->zone()), + zone_(graph->zone()), status_(UNUSED), current_instruction_(NULL), current_block_(NULL), diff --git a/src/isolate.cc b/src/isolate.cc index a6890c78e..6fcc926f2 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -256,7 +256,7 @@ void Isolate::PreallocatedStorageInit(size_t size) { void* Isolate::PreallocatedStorageNew(size_t size) { if (!preallocated_storage_preallocated_) { - return FreeStoreAllocationPolicy::New(size); + return FreeStoreAllocationPolicy().New(size); } ASSERT(free_list_.next_ != &free_list_); ASSERT(free_list_.previous_ != &free_list_); diff --git a/src/isolate.h b/src/isolate.h index f51b4e1a9..9aa1242f3 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -315,7 +315,7 @@ class ThreadLocalTop BASE_EMBEDDED { V(uint32_t, private_random_seed, 2) \ ISOLATE_INIT_DEBUG_ARRAY_LIST(V) -typedef List DebugObjectCache; +typedef List DebugObjectCache; #define ISOLATE_INIT_LIST(V) \ /* SerializerDeserializer state. */ \ diff --git a/src/jsregexp.cc b/src/jsregexp.cc index ee061ed71..f88511f4a 100644 --- a/src/jsregexp.cc +++ b/src/jsregexp.cc @@ -231,13 +231,14 @@ Handle RegExpImpl::Compile(Handle re, Handle RegExpImpl::Exec(Handle regexp, Handle subject, int index, - Handle last_match_info) { + Handle last_match_info, + Zone* zone) { switch (regexp->TypeTag()) { case JSRegExp::ATOM: return AtomExec(regexp, subject, index, last_match_info); case JSRegExp::IRREGEXP: { Handle result = - IrregexpExec(regexp, subject, index, last_match_info); + IrregexpExec(regexp, subject, index, last_match_info, zone); ASSERT(!result.is_null() || regexp->GetIsolate()->has_pending_exception()); return result; @@ -344,7 +345,8 @@ Handle RegExpImpl::AtomExec(Handle re, // If compilation fails, an exception is thrown and this function // returns false. bool RegExpImpl::EnsureCompiledIrregexp( - Handle re, Handle sample_subject, bool is_ascii) { + Handle re, Handle sample_subject, bool is_ascii, + Zone* zone) { Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii)); #ifdef V8_INTERPRETED_REGEXP if (compiled_code->IsByteArray()) return true; @@ -360,7 +362,7 @@ bool RegExpImpl::EnsureCompiledIrregexp( ASSERT(compiled_code->IsSmi()); return true; } - return CompileIrregexp(re, sample_subject, is_ascii); + return CompileIrregexp(re, sample_subject, is_ascii, zone); } @@ -382,7 +384,8 @@ static bool CreateRegExpErrorObjectAndThrow(Handle re, bool RegExpImpl::CompileIrregexp(Handle re, Handle sample_subject, - bool is_ascii) { + bool is_ascii, + Zone* zone) { // Compile the RegExp. Isolate* isolate = re->GetIsolate(); ZoneScope zone_scope(isolate, DELETE_ON_EXIT); @@ -433,7 +436,8 @@ bool RegExpImpl::CompileIrregexp(Handle re, flags.is_multiline(), pattern, sample_subject, - is_ascii); + is_ascii, + zone); if (result.error_message != NULL) { // Unable to compile regexp. Handle error_message = @@ -498,12 +502,13 @@ void RegExpImpl::IrregexpInitialize(Handle re, int RegExpImpl::IrregexpPrepare(Handle regexp, - Handle subject) { + Handle subject, + Zone* zone) { if (!subject->IsFlat()) FlattenString(subject); // Check the asciiness of the underlying storage. bool is_ascii = subject->IsAsciiRepresentationUnderneath(); - if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1; + if (!EnsureCompiledIrregexp(regexp, subject, is_ascii, zone)) return -1; #ifdef V8_INTERPRETED_REGEXP // Byte-code regexp needs space allocated for all its registers. @@ -536,7 +541,8 @@ int RegExpImpl::IrregexpExecRaw( Handle regexp, Handle subject, int index, - Vector output) { + Vector output, + Zone* zone) { Isolate* isolate = regexp->GetIsolate(); Handle irregexp(FixedArray::cast(regexp->data()), isolate); @@ -550,7 +556,7 @@ int RegExpImpl::IrregexpExecRaw( #ifndef V8_INTERPRETED_REGEXP ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2); do { - EnsureCompiledIrregexp(regexp, subject, is_ascii); + EnsureCompiledIrregexp(regexp, subject, is_ascii, zone); Handle code(IrregexpNativeCode(*irregexp, is_ascii), isolate); NativeRegExpMacroAssembler::Result res = NativeRegExpMacroAssembler::Match(code, @@ -576,7 +582,7 @@ int RegExpImpl::IrregexpExecRaw( // the, potentially, different subject (the string can switch between // being internal and external, and even between being ASCII and UC16, // but the characters are always the same). - IrregexpPrepare(regexp, subject); + IrregexpPrepare(regexp, subject, zone); is_ascii = subject->IsAsciiRepresentationUnderneath(); } while (true); UNREACHABLE(); @@ -611,7 +617,8 @@ int RegExpImpl::IrregexpExecRaw( Handle RegExpImpl::IrregexpExec(Handle jsregexp, Handle subject, int previous_index, - Handle last_match_info) { + Handle last_match_info, + Zone* zone) { Isolate* isolate = jsregexp->GetIsolate(); ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP); @@ -625,7 +632,7 @@ Handle RegExpImpl::IrregexpExec(Handle jsregexp, } #endif #endif - int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject); + int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject, zone); if (required_registers < 0) { // Compiling failed with an exception. ASSERT(isolate->has_pending_exception()); @@ -634,9 +641,10 @@ Handle RegExpImpl::IrregexpExec(Handle jsregexp, OffsetsVector registers(required_registers, isolate); - int res = RegExpImpl::IrregexpExecRaw( - jsregexp, subject, previous_index, Vector(registers.vector(), - registers.length())); + int res = RegExpImpl::IrregexpExecRaw(jsregexp, subject, previous_index, + Vector(registers.vector(), + registers.length()), + zone); if (res == RE_SUCCESS) { int capture_register_count = (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2; @@ -917,7 +925,8 @@ class FrequencyCollator { class RegExpCompiler { public: - RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii); + RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii, + Zone* zone); int AllocateRegister() { if (next_register_ >= RegExpMacroAssembler::kMaxRegister) { @@ -957,6 +966,8 @@ class RegExpCompiler { current_expansion_factor_ = value; } + Zone* zone() { return zone_; } + static const int kNoRegister = -1; private: @@ -970,6 +981,7 @@ class RegExpCompiler { bool reg_exp_too_big_; int current_expansion_factor_; FrequencyCollator frequency_collator_; + Zone* zone_; }; @@ -991,7 +1003,8 @@ static RegExpEngine::CompilationResult IrregexpRegExpTooBig() { // Attempts to compile the regexp using an Irregexp code generator. Returns // a fixed array or a null handle depending on whether it succeeded. -RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii) +RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii, + Zone* zone) : next_register_(2 * (capture_count + 1)), work_list_(NULL), recursion_depth_(0), @@ -999,8 +1012,9 @@ RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii) ascii_(ascii), reg_exp_too_big_(false), current_expansion_factor_(1), - frequency_collator_() { - accept_ = new EndNode(EndNode::ACCEPT); + frequency_collator_(), + zone_(zone) { + accept_ = new EndNode(EndNode::ACCEPT, zone); ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister); } @@ -2924,7 +2938,7 @@ void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) { EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); if (eats_at_least >= 1) { BoyerMooreLookahead* bm = - new BoyerMooreLookahead(eats_at_least, compiler); + new BoyerMooreLookahead(eats_at_least, compiler, zone()); FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; @@ -3505,7 +3519,7 @@ void BoyerMoorePositionInfo::SetAll() { BoyerMooreLookahead::BoyerMooreLookahead( - int length, RegExpCompiler* compiler) + int length, RegExpCompiler* compiler, Zone* zone) : length_(length), compiler_(compiler) { if (compiler->ascii()) { @@ -3515,7 +3529,7 @@ BoyerMooreLookahead::BoyerMooreLookahead( } bitmaps_ = new ZoneList(length); for (int i = 0; i < length; i++) { - bitmaps_->Add(new BoyerMoorePositionInfo()); + bitmaps_->Add(new BoyerMoorePositionInfo(zone)); } } @@ -3861,7 +3875,7 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); if (eats_at_least >= 1) { BoyerMooreLookahead* bm = - new BoyerMooreLookahead(eats_at_least, compiler); + new BoyerMooreLookahead(eats_at_least, compiler, zone()); GuardedAlternative alt0 = alternatives_->at(0); alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); @@ -4649,7 +4663,7 @@ RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler, RegExpNode* on_success) { ZoneList* alternatives = this->alternatives(); int length = alternatives->length(); - ChoiceNode* result = new ChoiceNode(length); + ChoiceNode* result = new ChoiceNode(length, compiler->zone()); for (int i = 0; i < length; i++) { GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler, on_success)); @@ -4772,7 +4786,7 @@ RegExpNode* RegExpQuantifier::ToNode(int min, // Unroll the optional matches up to max. RegExpNode* answer = on_success; for (int i = 0; i < max; i++) { - ChoiceNode* alternation = new ChoiceNode(2); + ChoiceNode* alternation = new ChoiceNode(2, compiler->zone()); if (is_greedy) { alternation->AddAlternative( GuardedAlternative(body->ToNode(compiler, answer))); @@ -4795,7 +4809,8 @@ RegExpNode* RegExpQuantifier::ToNode(int min, int reg_ctr = needs_counter ? compiler->AllocateRegister() : RegExpCompiler::kNoRegister; - LoopChoiceNode* center = new LoopChoiceNode(body->min_match() == 0); + LoopChoiceNode* center = new LoopChoiceNode(body->min_match() == 0, + compiler->zone()); if (not_at_start) center->set_not_at_start(); RegExpNode* loop_return = needs_counter ? static_cast(ActionNode::IncrementRegister(reg_ctr, center)) @@ -4864,7 +4879,7 @@ RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, int stack_pointer_register = compiler->AllocateRegister(); int position_register = compiler->AllocateRegister(); // The ChoiceNode to distinguish between a newline and end-of-input. - ChoiceNode* result = new ChoiceNode(2); + ChoiceNode* result = new ChoiceNode(2, compiler->zone()); // Create a newline atom. ZoneList* newline_ranges = new ZoneList(3); @@ -4951,10 +4966,12 @@ RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler, success = new NegativeSubmatchSuccess(stack_pointer_register, position_register, register_count, - register_start))); + register_start, + compiler->zone()))); ChoiceNode* choice_node = new NegativeLookaheadChoiceNode(body_alt, - GuardedAlternative(on_success)); + GuardedAlternative(on_success), + compiler->zone()); return ActionNode::BeginSubmatch(stack_pointer_register, position_register, choice_node); @@ -5827,11 +5844,12 @@ RegExpEngine::CompilationResult RegExpEngine::Compile( bool is_multiline, Handle pattern, Handle sample_subject, - bool is_ascii) { + bool is_ascii, + Zone* zone) { if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) { return IrregexpRegExpTooBig(); } - RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii); + RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii, zone); // Sample some characters from the middle of the string. static const int kSampleSize = 128; @@ -5869,7 +5887,7 @@ RegExpEngine::CompilationResult RegExpEngine::Compile( if (data->contains_anchor) { // Unroll loop once, to take care of the case that might start // at the start of input. - ChoiceNode* first_step_node = new ChoiceNode(2); + ChoiceNode* first_step_node = new ChoiceNode(2, zone); first_step_node->AddAlternative(GuardedAlternative(captured_body)); first_step_node->AddAlternative(GuardedAlternative( new TextNode(new RegExpCharacterClass('*'), loop_node))); @@ -5885,7 +5903,7 @@ RegExpEngine::CompilationResult RegExpEngine::Compile( if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion); } - if (node == NULL) node = new EndNode(EndNode::BACKTRACK); + if (node == NULL) node = new EndNode(EndNode::BACKTRACK, zone); data->node = node; Analysis analysis(ignore_case, is_ascii); analysis.EnsureAnalyzed(node); diff --git a/src/jsregexp.h b/src/jsregexp.h index 3601c1a1e..fa4ef5d09 100644 --- a/src/jsregexp.h +++ b/src/jsregexp.h @@ -78,7 +78,8 @@ class RegExpImpl { static Handle Exec(Handle regexp, Handle subject, int index, - Handle lastMatchInfo); + Handle lastMatchInfo, + Zone* zone); // Prepares a JSRegExp object with Irregexp-specific data. static void IrregexpInitialize(Handle re, @@ -107,7 +108,8 @@ class RegExpImpl { // as its "registers" argument. If the regexp cannot be compiled, // an exception is set as pending, and this function returns negative. static int IrregexpPrepare(Handle regexp, - Handle subject); + Handle subject, + Zone* zone); // Calculate the size of offsets vector for the case of global regexp // and the number of matches this vector is able to store. @@ -124,7 +126,8 @@ class RegExpImpl { static int IrregexpExecRaw(Handle regexp, Handle subject, int index, - Vector registers); + Vector registers, + Zone* zone); // Execute an Irregexp bytecode pattern. // On a successful match, the result is a JSArray containing @@ -133,7 +136,8 @@ class RegExpImpl { static Handle IrregexpExec(Handle regexp, Handle subject, int index, - Handle lastMatchInfo); + Handle lastMatchInfo, + Zone* zone); // Array index in the lastMatchInfo array. static const int kLastCaptureCount = 0; @@ -198,9 +202,11 @@ class RegExpImpl { static String* two_byte_cached_string_; static bool CompileIrregexp( - Handle re, Handle sample_subject, bool is_ascii); + Handle re, Handle sample_subject, bool is_ascii, + Zone* zone); static inline bool EnsureCompiledIrregexp( - Handle re, Handle sample_subject, bool is_ascii); + Handle re, Handle sample_subject, bool is_ascii, + Zone* zone); // Set the subject cache. The previous string buffer is not deleted, so the @@ -534,7 +540,8 @@ extern int kUninitializedRegExpNodePlaceHolder; class RegExpNode: public ZoneObject { public: - RegExpNode() : replacement_(NULL), trace_count_(0) { + explicit RegExpNode(Zone* zone) + : replacement_(NULL), trace_count_(0), zone_(zone) { bm_info_[0] = bm_info_[1] = NULL; } virtual ~RegExpNode(); @@ -628,6 +635,8 @@ class RegExpNode: public ZoneObject { return bm_info_[not_at_start ? 1 : 0]; } + Zone* zone() { return zone_; } + protected: enum LimitResult { DONE, CONTINUE }; RegExpNode* replacement_; @@ -649,6 +658,8 @@ class RegExpNode: public ZoneObject { // deferred operations in the current trace and generating a goto. int trace_count_; BoyerMooreLookahead* bm_info_[2]; + + Zone* zone_; }; @@ -682,7 +693,7 @@ class Interval { class SeqRegExpNode: public RegExpNode { public: explicit SeqRegExpNode(RegExpNode* on_success) - : on_success_(on_success) { } + : RegExpNode(on_success->zone()), on_success_(on_success) { } RegExpNode* on_success() { return on_success_; } void set_on_success(RegExpNode* node) { on_success_ = node; } virtual RegExpNode* FilterASCII(int depth); @@ -800,8 +811,8 @@ class TextNode: public SeqRegExpNode { TextNode(RegExpCharacterClass* that, RegExpNode* on_success) : SeqRegExpNode(on_success), - elms_(new ZoneList(1)) { - elms_->Add(TextElement::CharClass(that)); + elms_(new ZoneList(1, zone())) { + elms_->Add(TextElement::CharClass(that), zone()); } virtual void Accept(NodeVisitor* visitor); virtual void Emit(RegExpCompiler* compiler, Trace* trace); @@ -936,7 +947,8 @@ class BackReferenceNode: public SeqRegExpNode { class EndNode: public RegExpNode { public: enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; - explicit EndNode(Action action) : action_(action) { } + explicit EndNode(Action action, Zone* zone) + : RegExpNode(zone), action_(action) { } virtual void Accept(NodeVisitor* visitor); virtual void Emit(RegExpCompiler* compiler, Trace* trace); virtual int EatsAtLeast(int still_to_find, @@ -968,8 +980,9 @@ class NegativeSubmatchSuccess: public EndNode { NegativeSubmatchSuccess(int stack_pointer_reg, int position_reg, int clear_capture_count, - int clear_capture_start) - : EndNode(NEGATIVE_SUBMATCH_SUCCESS), + int clear_capture_start, + Zone* zone) + : EndNode(NEGATIVE_SUBMATCH_SUCCESS, zone), stack_pointer_register_(stack_pointer_reg), current_position_register_(position_reg), clear_capture_count_(clear_capture_count), @@ -1021,13 +1034,16 @@ class AlternativeGeneration; class ChoiceNode: public RegExpNode { public: - explicit ChoiceNode(int expected_size) - : alternatives_(new ZoneList(expected_size)), + explicit ChoiceNode(int expected_size, Zone* zone) + : RegExpNode(zone), + alternatives_(new ZoneList(expected_size, zone)), table_(NULL), not_at_start_(false), being_calculated_(false) { } virtual void Accept(NodeVisitor* visitor); - void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } + void AddAlternative(GuardedAlternative node) { + alternatives()->Add(node, zone()); + } ZoneList* alternatives() { return alternatives_; } DispatchTable* GetTable(bool ignore_case); virtual void Emit(RegExpCompiler* compiler, Trace* trace); @@ -1083,8 +1099,9 @@ class ChoiceNode: public RegExpNode { class NegativeLookaheadChoiceNode: public ChoiceNode { public: explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, - GuardedAlternative then_do_this) - : ChoiceNode(2) { + GuardedAlternative then_do_this, + Zone* zone) + : ChoiceNode(2, zone) { AddAlternative(this_must_fail); AddAlternative(then_do_this); } @@ -1116,8 +1133,8 @@ class NegativeLookaheadChoiceNode: public ChoiceNode { class LoopChoiceNode: public ChoiceNode { public: - explicit LoopChoiceNode(bool body_can_be_zero_length) - : ChoiceNode(2), + explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone) + : ChoiceNode(2, zone), loop_node_(NULL), continue_node_(NULL), body_can_be_zero_length_(body_can_be_zero_length) { } @@ -1202,15 +1219,15 @@ ContainedInLattice AddRange(ContainedInLattice a, class BoyerMoorePositionInfo : public ZoneObject { public: - BoyerMoorePositionInfo() - : map_(new ZoneList(kMapSize)), + explicit BoyerMoorePositionInfo(Zone* zone) + : map_(new ZoneList(kMapSize, zone)), map_count_(0), w_(kNotYet), s_(kNotYet), d_(kNotYet), surrogate_(kNotYet) { for (int i = 0; i < kMapSize; i++) { - map_->Add(false); + map_->Add(false, zone); } } @@ -1239,7 +1256,7 @@ class BoyerMoorePositionInfo : public ZoneObject { class BoyerMooreLookahead : public ZoneObject { public: - BoyerMooreLookahead(int length, RegExpCompiler* compiler); + BoyerMooreLookahead(int length, RegExpCompiler* compiler, Zone* zone); int length() { return length_; } int max_char() { return max_char_; } @@ -1589,7 +1606,7 @@ class RegExpEngine: public AllStatic { bool multiline, Handle pattern, Handle sample_subject, - bool is_ascii); + bool is_ascii, Zone* zone); static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); }; diff --git a/src/list-inl.h b/src/list-inl.h index 6cf3badc6..3eff5826a 100644 --- a/src/list-inl.h +++ b/src/list-inl.h @@ -35,25 +35,25 @@ namespace internal { template -void List::Add(const T& element) { +void List::Add(const T& element, P alloc) { if (length_ < capacity_) { data_[length_++] = element; } else { - List::ResizeAdd(element); + List::ResizeAdd(element, alloc); } } template -void List::AddAll(const List& other) { - AddAll(other.ToVector()); +void List::AddAll(const List& other, P alloc) { + AddAll(other.ToVector(), alloc); } template -void List::AddAll(const Vector& other) { +void List::AddAll(const Vector& other, P alloc) { int result_length = length_ + other.length(); - if (capacity_ < result_length) Resize(result_length); + if (capacity_ < result_length) Resize(result_length, alloc); for (int i = 0; i < other.length(); i++) { data_[length_ + i] = other.at(i); } @@ -64,13 +64,13 @@ void List::AddAll(const Vector& other) { // Use two layers of inlining so that the non-inlined function can // use the same implementation as the inlined version. template -void List::ResizeAdd(const T& element) { - ResizeAddInternal(element); +void List::ResizeAdd(const T& element, P alloc) { + ResizeAddInternal(element, alloc); } template -void List::ResizeAddInternal(const T& element) { +void List::ResizeAddInternal(const T& element, P alloc) { ASSERT(length_ >= capacity_); // Grow the list capacity by 100%, but make sure to let it grow // even when the capacity is zero (possible initial case). @@ -78,14 +78,14 @@ void List::ResizeAddInternal(const T& element) { // Since the element reference could be an element of the list, copy // it out of the old backing storage before resizing. T temp = element; - Resize(new_capacity); + Resize(new_capacity, alloc); data_[length_++] = temp; } template -void List::Resize(int new_capacity) { - T* new_data = List::NewData(new_capacity); +void List::Resize(int new_capacity, P alloc) { + T* new_data = NewData(new_capacity, alloc); memcpy(new_data, data_, capacity_ * sizeof(T)); List::DeleteData(data_); data_ = new_data; @@ -94,17 +94,17 @@ void List::Resize(int new_capacity) { template -Vector List::AddBlock(T value, int count) { +Vector List::AddBlock(T value, int count, P alloc) { int start = length_; - for (int i = 0; i < count; i++) Add(value); + for (int i = 0; i < count; i++) Add(value, alloc); return Vector(&data_[start], count); } template -void List::InsertAt(int index, const T& elm) { +void List::InsertAt(int index, const T& elm, P alloc) { ASSERT(index >= 0 && index <= length_); - Add(elm); + Add(elm, alloc); for (int i = length_ - 1; i > index; --i) { data_[i] = data_[i - 1]; } @@ -137,9 +137,9 @@ bool List::RemoveElement(const T& elm) { template -void List::Allocate(int length) { +void List::Allocate(int length, P allocator) { DeleteData(data_); - Initialize(length); + Initialize(length, allocator); length_ = length; } @@ -207,9 +207,9 @@ void List::Sort() { template -void List::Initialize(int capacity) { +void List::Initialize(int capacity, P allocator) { ASSERT(capacity >= 0); - data_ = (capacity > 0) ? NewData(capacity) : NULL; + data_ = (capacity > 0) ? NewData(capacity, allocator) : NULL; capacity_ = capacity; length_ = 0; } diff --git a/src/list.h b/src/list.h index 7350c0d44..3ca4a3fba 100644 --- a/src/list.h +++ b/src/list.h @@ -45,12 +45,18 @@ namespace internal { // the C free store or the zone; see zone.h. // Forward defined as -// template class List; -template +// template class List; +template class List { public: - List() { Initialize(0); } - INLINE(explicit List(int capacity)) { Initialize(capacity); } + explicit List(AllocationPolicy allocator = AllocationPolicy()) { + Initialize(0, allocator); + } + INLINE(explicit List(int capacity, + AllocationPolicy allocator = AllocationPolicy())) { + Initialize(capacity, allocator); + } INLINE(~List()) { DeleteData(data_); } // Deallocates memory used by the list and leaves the list in a consistent @@ -60,10 +66,13 @@ class List { Initialize(0); } - INLINE(void* operator new(size_t size)) { - return P::New(static_cast(size)); + INLINE(void* operator new(size_t size, + AllocationPolicy allocator = AllocationPolicy())) { + return allocator.New(static_cast(size)); + } + INLINE(void operator delete(void* p)) { + AllocationPolicy::Delete(p); } - INLINE(void operator delete(void* p, size_t)) { return P::Delete(p); } // Returns a reference to the element at index i. This reference is // not safe to use after operations that can change the list's @@ -87,21 +96,25 @@ class List { // Adds a copy of the given 'element' to the end of the list, // expanding the list if necessary. - void Add(const T& element); + void Add(const T& element, AllocationPolicy allocator = AllocationPolicy()); // Add all the elements from the argument list to this list. - void AddAll(const List& other); + void AddAll(const List& other, + AllocationPolicy allocator = AllocationPolicy()); // Add all the elements from the vector to this list. - void AddAll(const Vector& other); + void AddAll(const Vector& other, + AllocationPolicy allocator = AllocationPolicy()); // Inserts the element at the specific index. - void InsertAt(int index, const T& element); + void InsertAt(int index, const T& element, + AllocationPolicy allocator = AllocationPolicy()); // Added 'count' elements with the value 'value' and returns a // vector that allows access to the elements. The vector is valid // until the next change is made to this list. - Vector AddBlock(T value, int count); + Vector AddBlock(T value, int count, + AllocationPolicy allocator = AllocationPolicy()); // Removes the i'th element without deleting it even if T is a // pointer type; moves all elements above i "down". Returns the @@ -118,7 +131,8 @@ class List { INLINE(T RemoveLast()) { return Remove(length_ - 1); } // Deletes current list contents and allocates space for 'length' elements. - INLINE(void Allocate(int length)); + INLINE(void Allocate(int length, + AllocationPolicy allocator = AllocationPolicy())); // Clears the list by setting the length to zero. Even if T is a // pointer type, clearing the list doesn't delete the entries. @@ -142,26 +156,31 @@ class List { void Sort(int (*cmp)(const T* x, const T* y)); void Sort(); - INLINE(void Initialize(int capacity)); + INLINE(void Initialize(int capacity, + AllocationPolicy allocator = AllocationPolicy())); private: T* data_; int capacity_; int length_; - INLINE(T* NewData(int n)) { return static_cast(P::New(n * sizeof(T))); } - INLINE(void DeleteData(T* data)) { P::Delete(data); } + INLINE(T* NewData(int n, AllocationPolicy allocator)) { + return static_cast(allocator.New(n * sizeof(T))); + } + INLINE(void DeleteData(T* data)) { + AllocationPolicy::Delete(data); + } // Increase the capacity of a full list, and add an element. // List must be full already. - void ResizeAdd(const T& element); + void ResizeAdd(const T& element, AllocationPolicy allocator); // Inlined implementation of ResizeAdd, shared by inlined and // non-inlined versions of ResizeAdd. - void ResizeAddInternal(const T& element); + void ResizeAddInternal(const T& element, AllocationPolicy allocator); // Resize the list. - void Resize(int new_capacity); + void Resize(int new_capacity, AllocationPolicy allocator); DISALLOW_COPY_AND_ASSIGN(List); }; diff --git a/src/lithium.h b/src/lithium.h index 2ccbf56c5..1bab5ac34 100644 --- a/src/lithium.h +++ b/src/lithium.h @@ -459,7 +459,8 @@ class LEnvironment: public ZoneObject { int parameter_count, int argument_count, int value_count, - LEnvironment* outer) + LEnvironment* outer, + Zone* zone) : closure_(closure), frame_type_(frame_type), arguments_stack_height_(argument_count), @@ -472,7 +473,8 @@ class LEnvironment: public ZoneObject { is_tagged_(value_count, closure->GetHeap()->isolate()->zone()), spilled_registers_(NULL), spilled_double_registers_(NULL), - outer_(outer) { } + outer_(outer), + zone_(zone) { } Handle closure() const { return closure_; } FrameType frame_type() const { return frame_type_; } @@ -520,6 +522,8 @@ class LEnvironment: public ZoneObject { void PrintTo(StringStream* stream); + Zone* zone() { return zone_; } + private: Handle closure_; FrameType frame_type_; @@ -539,6 +543,8 @@ class LEnvironment: public ZoneObject { LOperand** spilled_double_registers_; LEnvironment* outer_; + + Zone* zone_; }; diff --git a/src/parser.cc b/src/parser.cc index 3a7a973d4..778527ff5 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -86,8 +86,8 @@ class PositionStack { }; -RegExpBuilder::RegExpBuilder() - : zone_(Isolate::Current()->zone()), +RegExpBuilder::RegExpBuilder(Zone* zone) + : zone_(zone), pending_empty_(false), characters_(NULL), terms_(), @@ -535,7 +535,8 @@ Parser::FunctionState::~FunctionState() { Parser::Parser(Handle