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);
}
// 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); }
};
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_;
};
+struct PreallocatedStorageAllocationPolicy {
+ INLINE(void* New(size_t size));
+ INLINE(static void Delete(void* ptr));
+};
+
+
} } // namespace v8::internal
#endif // V8_ALLOCATION_H_
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;
: chunk_(NULL),
info_(info),
graph_(graph),
- zone_(graph->isolate()->zone()),
+ zone_(graph->zone()),
status_(UNUSED),
current_instruction_(NULL),
current_block_(NULL),
++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();
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));
}
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),
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();
}
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.
Safepoint::Kind expected_safepoint_kind_;
+ Zone* zone_;
+
class PushSafepointRegistersScope BASE_EMBEDDED {
public:
PushSafepointRegistersScope(LCodeGen* codegen,
public:
DECLARE_NODE_TYPE(Block)
- void AddStatement(Statement* statement) { statements_.Add(statement); }
+ void AddStatement(Statement* statement, Zone* zone) {
+ statements_.Add(statement, zone);
+ }
ZoneList<Statement*>* statements() { return &statements_; }
bool is_initializer_block() const { return is_initializer_block_; }
}
if (graph != NULL) {
- Handle<Code> optimized_code = graph->Compile(info);
+ Handle<Code> optimized_code = graph->Compile(info, graph->zone());
if (!optimized_code.is_null()) {
info->SetCode(optimized_code);
FinishOptimization(info->closure(), start);
}
-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) |
// 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);
}
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());
}
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<ByteArray> CreateByteArray();
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_; }
void StoreArgumentsObject();
void MarkDuplicate();
+ Zone* zone() { return zone_; }
+
static int NumberOfOperandsFor(Opcode opcode);
#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
private:
TranslationBuffer* buffer_;
int index_;
+ Zone* zone_;
};
// A map from property names to getter/setter pairs allocated in the zone.
class AccessorTable: public TemplateHashMap<Literal,
ObjectLiteral::Accessors,
- ZoneListAllocationPolicy> {
+ ZoneAllocationPolicy> {
public:
explicit AccessorTable(Zone* zone) :
- TemplateHashMap<Literal,
- ObjectLiteral::Accessors,
- ZoneListAllocationPolicy>(Literal::Match),
+ TemplateHashMap<Literal, ObjectLiteral::Accessors,
+ ZoneAllocationPolicy>(Literal::Match),
zone_(zone) { }
Iterator lookup(Literal* literal) {
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();
// 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
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<FreeStoreAllocationPolicy> HashMap;
-template<class P>
-TemplateHashMapImpl<P>::TemplateHashMapImpl(MatchFun match,
- uint32_t initial_capacity) {
+template<class AllocationPolicy>
+TemplateHashMapImpl<AllocationPolicy>::TemplateHashMapImpl(
+ MatchFun match, uint32_t initial_capacity, AllocationPolicy allocator) {
match_ = match;
- Initialize(initial_capacity);
+ Initialize(initial_capacity, allocator);
}
-template<class P>
-TemplateHashMapImpl<P>::~TemplateHashMapImpl() {
- P::Delete(map_);
+template<class AllocationPolicy>
+TemplateHashMapImpl<AllocationPolicy>::~TemplateHashMapImpl() {
+ AllocationPolicy::Delete(map_);
}
-template<class P>
-typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Lookup(
- void* key, uint32_t hash, bool insert) {
+template<class AllocationPolicy>
+typename TemplateHashMapImpl<AllocationPolicy>::Entry*
+TemplateHashMapImpl<AllocationPolicy>::Lookup(
+ void* key, uint32_t hash, bool insert, AllocationPolicy allocator) {
// Find a matching entry.
Entry* p = Probe(key, hash);
if (p->key != NULL) {
// Grow the map if we reached >= 80% occupancy.
if (occupancy_ + occupancy_/4 >= capacity_) {
- Resize();
+ Resize(allocator);
p = Probe(key, hash);
}
}
-template<class P>
-void* TemplateHashMapImpl<P>::Remove(void* key, uint32_t hash) {
+template<class AllocationPolicy>
+void* TemplateHashMapImpl<AllocationPolicy>::Remove(void* key, uint32_t hash) {
// Lookup the entry for the key to remove.
Entry* p = Probe(key, hash);
if (p->key == NULL) {
}
-template<class P>
-void TemplateHashMapImpl<P>::Clear() {
+template<class AllocationPolicy>
+void TemplateHashMapImpl<AllocationPolicy>::Clear() {
// Mark all entries as empty.
const Entry* end = map_end();
for (Entry* p = map_; p < end; p++) {
}
-template<class P>
-typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Start() const {
+template<class AllocationPolicy>
+typename TemplateHashMapImpl<AllocationPolicy>::Entry*
+ TemplateHashMapImpl<AllocationPolicy>::Start() const {
return Next(map_ - 1);
}
-template<class P>
-typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Next(Entry* p)
- const {
+template<class AllocationPolicy>
+typename TemplateHashMapImpl<AllocationPolicy>::Entry*
+ TemplateHashMapImpl<AllocationPolicy>::Next(Entry* p) const {
const Entry* end = map_end();
ASSERT(map_ - 1 <= p && p < end);
for (p++; p < end; p++) {
}
-template<class P>
-typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Probe(void* key,
- uint32_t hash) {
+template<class AllocationPolicy>
+typename TemplateHashMapImpl<AllocationPolicy>::Entry*
+ TemplateHashMapImpl<AllocationPolicy>::Probe(void* key, uint32_t hash) {
ASSERT(key != NULL);
ASSERT(IsPowerOf2(capacity_));
}
-template<class P>
-void TemplateHashMapImpl<P>::Initialize(uint32_t capacity) {
+template<class AllocationPolicy>
+void TemplateHashMapImpl<AllocationPolicy>::Initialize(
+ uint32_t capacity, AllocationPolicy allocator) {
ASSERT(IsPowerOf2(capacity));
- map_ = reinterpret_cast<Entry*>(P::New(capacity * sizeof(Entry)));
+ map_ = reinterpret_cast<Entry*>(allocator.New(capacity * sizeof(Entry)));
if (map_ == NULL) {
v8::internal::FatalProcessOutOfMemory("HashMap::Initialize");
return;
}
-template<class P>
-void TemplateHashMapImpl<P>::Resize() {
+template<class AllocationPolicy>
+void TemplateHashMapImpl<AllocationPolicy>::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++) {
}
// Delete old map.
- P::Delete(map);
+ AllocationPolicy::Delete(map);
}
};
TemplateHashMap(
- typename TemplateHashMapImpl<AllocationPolicy>::MatchFun match)
- : TemplateHashMapImpl<AllocationPolicy>(match) { }
+ typename TemplateHashMapImpl<AllocationPolicy>::MatchFun match,
+ AllocationPolicy allocator = AllocationPolicy())
+ : TemplateHashMapImpl<AllocationPolicy>(
+ match,
+ TemplateHashMapImpl<AllocationPolicy>::kDefaultHashMapCapacity,
+ allocator) { }
Iterator begin() const { return Iterator(this, this->Start()); }
Iterator end() const { return Iterator(this, NULL); }
}
-Handle<Code> HGraph::Compile(CompilationInfo* info) {
+Handle<Code> HGraph::Compile(CompilationInfo* info, Zone* zone) {
int values = GetMaximumValueID();
if (values > LUnallocated::kMaxVirtualRegisters) {
if (FLAG_trace_bailout) {
}
MacroAssembler assembler(info->isolate(), NULL, 0);
- LCodeGen generator(chunk, &assembler, info);
+ LCodeGen generator(chunk, &assembler, info, zone);
chunk->MarkEmptyBlocks();
void CollectPhis();
- Handle<Code> Compile(CompilationInfo* info);
+ Handle<Code> Compile(CompilationInfo* info, Zone* zone);
void set_undefined_constant(HConstant* constant) {
undefined_constant_.set(constant);
++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();
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));
}
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),
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();
}
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;
Safepoint::Kind expected_safepoint_kind_;
+ Zone* zone_;
+
class PushSafepointRegistersScope BASE_EMBEDDED {
public:
explicit PushSafepointRegistersScope(LCodeGen* codegen)
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;
: chunk_(NULL),
info_(info),
graph_(graph),
- zone_(graph->isolate()->zone()),
+ zone_(graph->zone()),
status_(UNUSED),
current_instruction_(NULL),
current_block_(NULL),
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_);
V(uint32_t, private_random_seed, 2) \
ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
-typedef List<HeapObject*, PreallocatedStorage> DebugObjectCache;
+typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache;
#define ISOLATE_INIT_LIST(V) \
/* SerializerDeserializer state. */ \
Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Handle<JSArray> last_match_info) {
+ Handle<JSArray> last_match_info,
+ Zone* zone) {
switch (regexp->TypeTag()) {
case JSRegExp::ATOM:
return AtomExec(regexp, subject, index, last_match_info);
case JSRegExp::IRREGEXP: {
Handle<Object> 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;
// If compilation fails, an exception is thrown and this function
// returns false.
bool RegExpImpl::EnsureCompiledIrregexp(
- Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii) {
+ Handle<JSRegExp> re, Handle<String> 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;
ASSERT(compiled_code->IsSmi());
return true;
}
- return CompileIrregexp(re, sample_subject, is_ascii);
+ return CompileIrregexp(re, sample_subject, is_ascii, zone);
}
bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
Handle<String> sample_subject,
- bool is_ascii) {
+ bool is_ascii,
+ Zone* zone) {
// Compile the RegExp.
Isolate* isolate = re->GetIsolate();
ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
flags.is_multiline(),
pattern,
sample_subject,
- is_ascii);
+ is_ascii,
+ zone);
if (result.error_message != NULL) {
// Unable to compile regexp.
Handle<String> error_message =
int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
- Handle<String> subject) {
+ Handle<String> 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.
Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Vector<int> output) {
+ Vector<int> output,
+ Zone* zone) {
Isolate* isolate = regexp->GetIsolate();
Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate);
#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> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
NativeRegExpMacroAssembler::Result res =
NativeRegExpMacroAssembler::Match(code,
// 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();
Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
Handle<String> subject,
int previous_index,
- Handle<JSArray> last_match_info) {
+ Handle<JSArray> last_match_info,
+ Zone* zone) {
Isolate* isolate = jsregexp->GetIsolate();
ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP);
}
#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());
OffsetsVector registers(required_registers, isolate);
- int res = RegExpImpl::IrregexpExecRaw(
- jsregexp, subject, previous_index, Vector<int>(registers.vector(),
- registers.length()));
+ int res = RegExpImpl::IrregexpExecRaw(jsregexp, subject, previous_index,
+ Vector<int>(registers.vector(),
+ registers.length()),
+ zone);
if (res == RE_SUCCESS) {
int capture_register_count =
(IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2;
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) {
current_expansion_factor_ = value;
}
+ Zone* zone() { return zone_; }
+
static const int kNoRegister = -1;
private:
bool reg_exp_too_big_;
int current_expansion_factor_;
FrequencyCollator frequency_collator_;
+ Zone* zone_;
};
// 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),
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);
}
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;
BoyerMooreLookahead::BoyerMooreLookahead(
- int length, RegExpCompiler* compiler)
+ int length, RegExpCompiler* compiler, Zone* zone)
: length_(length),
compiler_(compiler) {
if (compiler->ascii()) {
}
bitmaps_ = new ZoneList<BoyerMoorePositionInfo*>(length);
for (int i = 0; i < length; i++) {
- bitmaps_->Add(new BoyerMoorePositionInfo());
+ bitmaps_->Add(new BoyerMoorePositionInfo(zone));
}
}
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);
RegExpNode* on_success) {
ZoneList<RegExpTree*>* 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));
// 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)));
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<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
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<CharacterRange>* newline_ranges =
new ZoneList<CharacterRange>(3);
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);
bool is_multiline,
Handle<String> pattern,
Handle<String> 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;
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)));
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);
static Handle<Object> Exec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Handle<JSArray> lastMatchInfo);
+ Handle<JSArray> lastMatchInfo,
+ Zone* zone);
// Prepares a JSRegExp object with Irregexp-specific data.
static void IrregexpInitialize(Handle<JSRegExp> re,
// 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<JSRegExp> regexp,
- Handle<String> subject);
+ Handle<String> 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.
static int IrregexpExecRaw(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Vector<int> registers);
+ Vector<int> registers,
+ Zone* zone);
// Execute an Irregexp bytecode pattern.
// On a successful match, the result is a JSArray containing
static Handle<Object> IrregexpExec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
- Handle<JSArray> lastMatchInfo);
+ Handle<JSArray> lastMatchInfo,
+ Zone* zone);
// Array index in the lastMatchInfo array.
static const int kLastCaptureCount = 0;
static String* two_byte_cached_string_;
static bool CompileIrregexp(
- Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii);
+ Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii,
+ Zone* zone);
static inline bool EnsureCompiledIrregexp(
- Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii);
+ Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii,
+ Zone* zone);
// Set the subject cache. The previous string buffer is not deleted, so the
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();
return bm_info_[not_at_start ? 1 : 0];
}
+ Zone* zone() { return zone_; }
+
protected:
enum LimitResult { DONE, CONTINUE };
RegExpNode* replacement_;
// deferred operations in the current trace and generating a goto.
int trace_count_;
BoyerMooreLookahead* bm_info_[2];
+
+ Zone* zone_;
};
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);
TextNode(RegExpCharacterClass* that,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
- elms_(new ZoneList<TextElement>(1)) {
- elms_->Add(TextElement::CharClass(that));
+ elms_(new ZoneList<TextElement>(1, zone())) {
+ elms_->Add(TextElement::CharClass(that), zone());
}
virtual void Accept(NodeVisitor* visitor);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
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,
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),
class ChoiceNode: public RegExpNode {
public:
- explicit ChoiceNode(int expected_size)
- : alternatives_(new ZoneList<GuardedAlternative>(expected_size)),
+ explicit ChoiceNode(int expected_size, Zone* zone)
+ : RegExpNode(zone),
+ alternatives_(new ZoneList<GuardedAlternative>(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<GuardedAlternative>* alternatives() { return alternatives_; }
DispatchTable* GetTable(bool ignore_case);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
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);
}
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) { }
class BoyerMoorePositionInfo : public ZoneObject {
public:
- BoyerMoorePositionInfo()
- : map_(new ZoneList<bool>(kMapSize)),
+ explicit BoyerMoorePositionInfo(Zone* zone)
+ : map_(new ZoneList<bool>(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);
}
}
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_; }
bool multiline,
Handle<String> pattern,
Handle<String> sample_subject,
- bool is_ascii);
+ bool is_ascii, Zone* zone);
static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
};
template<typename T, class P>
-void List<T, P>::Add(const T& element) {
+void List<T, P>::Add(const T& element, P alloc) {
if (length_ < capacity_) {
data_[length_++] = element;
} else {
- List<T, P>::ResizeAdd(element);
+ List<T, P>::ResizeAdd(element, alloc);
}
}
template<typename T, class P>
-void List<T, P>::AddAll(const List<T, P>& other) {
- AddAll(other.ToVector());
+void List<T, P>::AddAll(const List<T, P>& other, P alloc) {
+ AddAll(other.ToVector(), alloc);
}
template<typename T, class P>
-void List<T, P>::AddAll(const Vector<T>& other) {
+void List<T, P>::AddAll(const Vector<T>& 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);
}
// Use two layers of inlining so that the non-inlined function can
// use the same implementation as the inlined version.
template<typename T, class P>
-void List<T, P>::ResizeAdd(const T& element) {
- ResizeAddInternal(element);
+void List<T, P>::ResizeAdd(const T& element, P alloc) {
+ ResizeAddInternal(element, alloc);
}
template<typename T, class P>
-void List<T, P>::ResizeAddInternal(const T& element) {
+void List<T, P>::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).
// 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<typename T, class P>
-void List<T, P>::Resize(int new_capacity) {
- T* new_data = List<T, P>::NewData(new_capacity);
+void List<T, P>::Resize(int new_capacity, P alloc) {
+ T* new_data = NewData(new_capacity, alloc);
memcpy(new_data, data_, capacity_ * sizeof(T));
List<T, P>::DeleteData(data_);
data_ = new_data;
template<typename T, class P>
-Vector<T> List<T, P>::AddBlock(T value, int count) {
+Vector<T> List<T, P>::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<T>(&data_[start], count);
}
template<typename T, class P>
-void List<T, P>::InsertAt(int index, const T& elm) {
+void List<T, P>::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];
}
template<typename T, class P>
-void List<T, P>::Allocate(int length) {
+void List<T, P>::Allocate(int length, P allocator) {
DeleteData(data_);
- Initialize(length);
+ Initialize(length, allocator);
length_ = length;
}
template<typename T, class P>
-void List<T, P>::Initialize(int capacity) {
+void List<T, P>::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;
}
// the C free store or the zone; see zone.h.
// Forward defined as
-// template <typename T, class P = FreeStoreAllocationPolicy> class List;
-template <typename T, class P>
+// template <typename T,
+// class AllocationPolicy = FreeStoreAllocationPolicy> class List;
+template <typename T, class AllocationPolicy>
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
Initialize(0);
}
- INLINE(void* operator new(size_t size)) {
- return P::New(static_cast<int>(size));
+ INLINE(void* operator new(size_t size,
+ AllocationPolicy allocator = AllocationPolicy())) {
+ return allocator.New(static_cast<int>(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
// 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<T, P>& other);
+ void AddAll(const List<T, AllocationPolicy>& other,
+ AllocationPolicy allocator = AllocationPolicy());
// Add all the elements from the vector to this list.
- void AddAll(const Vector<T>& other);
+ void AddAll(const Vector<T>& 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<T> AddBlock(T value, int count);
+ Vector<T> 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
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.
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<T*>(P::New(n * sizeof(T))); }
- INLINE(void DeleteData(T* data)) { P::Delete(data); }
+ INLINE(T* NewData(int n, AllocationPolicy allocator)) {
+ return static_cast<T*>(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);
};
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),
is_tagged_(value_count, closure->GetHeap()->isolate()->zone()),
spilled_registers_(NULL),
spilled_double_registers_(NULL),
- outer_(outer) { }
+ outer_(outer),
+ zone_(zone) { }
Handle<JSFunction> closure() const { return closure_; }
FrameType frame_type() const { return frame_type_; }
void PrintTo(StringStream* stream);
+ Zone* zone() { return zone_; }
+
private:
Handle<JSFunction> closure_;
FrameType frame_type_;
LOperand** spilled_double_registers_;
LEnvironment* outer_;
+
+ Zone* zone_;
};
};
-RegExpBuilder::RegExpBuilder()
- : zone_(Isolate::Current()->zone()),
+RegExpBuilder::RegExpBuilder(Zone* zone)
+ : zone_(zone),
pending_empty_(false),
characters_(NULL),
terms_(),
Parser::Parser(Handle<Script> script,
int parser_flags,
v8::Extension* extension,
- ScriptDataImpl* pre_data)
+ ScriptDataImpl* pre_data,
+ Zone* zone)
: isolate_(script->GetIsolate()),
symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
script_(script),
allow_lazy_((parser_flags & kAllowLazy) != 0),
allow_modules_((parser_flags & kAllowModules) != 0),
stack_overflow_(false),
- parenthesized_function_(false) {
+ parenthesized_function_(false),
+ zone_(zone) {
isolate_->set_ast_node_id(0);
if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) {
scanner().SetHarmonyScoping(true);
while (peek() != Token::RBRACE) {
Statement* stat = ParseModuleElement(NULL, CHECK_OK);
if (stat && !stat->IsEmpty()) {
- body->AddStatement(stat);
+ body->AddStatement(stat, zone());
block_finder.Update(stat);
}
}
if (statement) {
statement->set_statement_pos(statement_pos);
}
- if (result) result->AddStatement(statement);
+ if (result) result->AddStatement(statement, zone());
return result;
}
while (peek() != Token::RBRACE) {
Statement* stat = ParseStatement(NULL, CHECK_OK);
if (stat && !stat->IsEmpty()) {
- result->AddStatement(stat);
+ result->AddStatement(stat, zone());
block_finder.Update(stat);
}
}
while (peek() != Token::RBRACE) {
Statement* stat = ParseBlockElement(NULL, CHECK_OK);
if (stat && !stat->IsEmpty()) {
- body->AddStatement(stat);
+ body->AddStatement(stat, zone());
block_finder.Update(stat);
}
}
arguments);
}
- block->AddStatement(factory()->NewExpressionStatement(initialize));
+ block->AddStatement(factory()->NewExpressionStatement(initialize),
+ zone());
} else if (needs_init) {
// Constant initializations always assign to the declared constant which
// is always at the function scope level. This is only relevant for
ASSERT(value != NULL);
Assignment* assignment =
factory()->NewAssignment(init_op, proxy, value, position);
- block->AddStatement(factory()->NewExpressionStatement(assignment));
+ block->AddStatement(factory()->NewExpressionStatement(assignment),
+ zone());
value = NULL;
}
initialization_scope->NewUnresolved(factory(), name);
Assignment* assignment =
factory()->NewAssignment(init_op, proxy, value, position);
- block->AddStatement(factory()->NewExpressionStatement(assignment));
+ block->AddStatement(factory()->NewExpressionStatement(assignment),
+ zone());
}
if (fni_ != NULL) fni_->Leave();
index, try_block, catch_scope, catch_variable, catch_block);
statement->set_escaping_targets(try_collector.targets());
try_block = factory()->NewBlock(NULL, 1, false);
- try_block->AddStatement(statement);
+ try_block->AddStatement(statement, zone());
catch_block = NULL; // Clear to indicate it's been handled.
}
Statement* body = ParseStatement(NULL, CHECK_OK);
loop->Initialize(each, enumerable, body);
Block* result = factory()->NewBlock(NULL, 2, false);
- result->AddStatement(variable_statement);
- result->AddStatement(loop);
+ result->AddStatement(variable_statement, zone());
+ result->AddStatement(loop, zone());
top_scope_ = saved_scope;
for_scope->set_end_position(scanner().location().end_pos);
for_scope = for_scope->FinalizeBlockScope();
Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
Statement* assignment_statement =
factory()->NewExpressionStatement(assignment);
- body_block->AddStatement(variable_statement);
- body_block->AddStatement(assignment_statement);
- body_block->AddStatement(body);
+ body_block->AddStatement(variable_statement, zone());
+ body_block->AddStatement(assignment_statement, zone());
+ body_block->AddStatement(body, zone());
loop->Initialize(temp_proxy, enumerable, body_block);
top_scope_ = saved_scope;
for_scope->set_end_position(scanner().location().end_pos);
// }
ASSERT(init != NULL);
Block* result = factory()->NewBlock(NULL, 2, false);
- result->AddStatement(init);
- result->AddStatement(loop);
+ result->AddStatement(init, zone());
+ result->AddStatement(loop, zone());
result->set_scope(for_scope);
if (loop) loop->Initialize(NULL, cond, next, body);
return result;
// Atom Quantifier
RegExpTree* RegExpParser::ParseDisjunction() {
// Used to store current state while parsing subexpressions.
- RegExpParserState initial_state(NULL, INITIAL, 0);
+ RegExpParserState initial_state(NULL, INITIAL, 0, zone());
RegExpParserState* stored_state = &initial_state;
// Cache the builder in a local variable for quick access.
RegExpBuilder* builder = initial_state.builder();
captures_->Add(NULL);
}
// Store current state and begin new disjunction parsing.
- stored_state = new(zone()) RegExpParserState(stored_state,
- type,
- captures_started());
+ stored_state = new(zone()) RegExpParserState(stored_state, type,
+ captures_started(), zone());
builder = stored_state->builder();
continue;
}
}
if (info->is_lazy()) {
ASSERT(!info->is_eval());
- Parser parser(script, parsing_flags, NULL, NULL);
+ Parser parser(script, parsing_flags, NULL, NULL, info->isolate()->zone());
if (info->shared_info()->is_function()) {
result = parser.ParseLazy(info);
} else {
}
} else {
ScriptDataImpl* pre_data = info->pre_parse_data();
- Parser parser(script, parsing_flags, info->extension(), pre_data);
+ Parser parser(script, parsing_flags, info->extension(), pre_data,
+ info->isolate()->zone());
if (pre_data != NULL && pre_data->has_error()) {
Scanner::Location loc = pre_data->MessageLocation();
const char* message = pre_data->BuildMessage();
// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
class RegExpBuilder: public ZoneObject {
public:
- RegExpBuilder();
+ explicit RegExpBuilder(Zone* zone);
void AddCharacter(uc16 character);
// "Adds" an empty expression. Does nothing except consume a
// following quantifier
public:
RegExpParserState(RegExpParserState* previous_state,
SubexpressionType group_type,
- int disjunction_capture_index)
+ int disjunction_capture_index,
+ Zone* zone)
: previous_state_(previous_state),
- builder_(new RegExpBuilder()),
+ builder_(new RegExpBuilder(zone)),
group_type_(group_type),
disjunction_capture_index_(disjunction_capture_index) {}
// Parser state of containing expression, if any.
Parser(Handle<Script> script,
int parsing_flags, // Combination of ParsingFlags
v8::Extension* extension,
- ScriptDataImpl* pre_data);
+ ScriptDataImpl* pre_data,
+ Zone* zone);
virtual ~Parser() {
delete reusable_preparser_;
reusable_preparser_ = NULL;
ZoneScope* zone_scope);
Isolate* isolate() { return isolate_; }
- Zone* zone() { return isolate_->zone(); }
+ Zone* zone() { return zone_; }
// Called by ParseProgram after setting up the scanner.
FunctionLiteral* DoParseProgram(CompilationInfo* info,
// so never lazily compile it.
bool parenthesized_function_;
+ Zone* zone_;
friend class BlockState;
friend class FunctionState;
};
Handle<Object> result = RegExpImpl::Exec(regexp,
subject,
index,
- last_match_info);
+ last_match_info,
+ isolate->zone());
if (result.is_null()) return Failure::Exception();
return *result;
}
Handle<Object> match = RegExpImpl::Exec(regexp_handle,
subject_handle,
0,
- last_match_info_handle);
+ last_match_info_handle,
+ isolate->zone());
if (match.is_null()) {
return Failure::Exception();
}
match = RegExpImpl::Exec(regexp_handle,
subject_handle,
next,
- last_match_info_handle);
+ last_match_info_handle,
+ isolate->zone());
if (match.is_null()) {
return Failure::Exception();
}
Handle<Object> match = RegExpImpl::Exec(regexp_handle,
subject_handle,
0,
- last_match_info_handle);
+ last_match_info_handle,
+ isolate->zone());
if (match.is_null()) return Failure::Exception();
if (match->IsNull()) return *subject_handle;
match = RegExpImpl::Exec(regexp_handle,
subject_handle,
next,
- last_match_info_handle);
+ last_match_info_handle,
+ isolate->zone());
if (match.is_null()) return Failure::Exception();
if (match->IsNull()) break;
CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
HandleScope handles;
- Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info);
+ Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info,
+ isolate->zone());
if (match.is_null()) {
return Failure::Exception();
offsets.Add(start);
offsets.Add(end);
if (start == end) if (++end > length) break;
- match = RegExpImpl::Exec(regexp, subject, end, regexp_info);
+ match = RegExpImpl::Exec(regexp, subject, end, regexp_info,
+ isolate->zone());
if (match.is_null()) {
return Failure::Exception();
}
int match_start = -1;
int match_end = 0;
int pos = 0;
- int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject);
+ int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject,
+ isolate->zone());
if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION;
int max_matches;
int num_matches = RegExpImpl::IrregexpExecRaw(regexp,
subject,
pos,
- register_vector);
+ register_vector,
+ isolate->zone());
if (num_matches > 0) {
for (int match_index = 0; match_index < num_matches; match_index++) {
int32_t* current_match = ®ister_vector[match_index * 2];
FixedArrayBuilder* builder) {
ASSERT(subject->IsFlat());
- int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject);
+ int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject,
+ isolate->zone());
if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION;
int max_matches;
int num_matches = RegExpImpl::IrregexpExecRaw(regexp,
subject,
0,
- register_vector);
+ register_vector,
+ isolate->zone());
int capture_count = regexp->CaptureCount();
int subject_length = subject->length();
num_matches = RegExpImpl::IrregexpExecRaw(regexp,
subject,
pos,
- register_vector);
+ register_vector,
+ isolate->zone());
} while (num_matches > 0);
if (num_matches != RegExpImpl::RE_EXCEPTION) {
static const int kNoDeoptimizationIndex =
(1 << (SafepointEntry::kDeoptIndexBits)) - 1;
- void DefinePointerSlot(int index) { indexes_->Add(index); }
+ void DefinePointerSlot(int index, Zone* zone) { indexes_->Add(index, zone); }
void DefinePointerRegister(Register reg);
private:
class SafepointTableBuilder BASE_EMBEDDED {
public:
- SafepointTableBuilder()
- : deoptimization_info_(32),
- deopt_index_list_(32),
- indexes_(32),
- registers_(32),
+ explicit SafepointTableBuilder(Zone* zone)
+ : deoptimization_info_(32, zone),
+ deopt_index_list_(32, zone),
+ indexes_(32, zone),
+ registers_(32, zone),
emitted_(false),
- last_lazy_safepoint_(0) { }
+ last_lazy_safepoint_(0),
+ zone_(zone) { }
// Get the offset of the emitted safepoint table in the code.
unsigned GetCodeOffset() const;
bool emitted_;
int last_lazy_safepoint_;
+ Zone* zone_;
+
DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder);
};
template<typename Config, class Allocator>
-bool SplayTree<Config, Allocator>::Insert(const Key& key, Locator* locator) {
+bool SplayTree<Config, Allocator>::Insert(const Key& key,
+ Locator* locator,
+ Allocator allocator) {
if (is_empty()) {
// If the tree is empty, insert the new node.
- root_ = new Node(key, Config::NoValue());
+ root_ = new(allocator) Node(key, Config::NoValue());
} else {
// Splay on the key to move the last node on the search path
// for the key to the root of the tree.
return false;
}
// Insert the new node.
- Node* node = new Node(key, Config::NoValue());
+ Node* node = new(allocator) Node(key, Config::NoValue());
InsertInternal(cmp, node);
}
locator->bind(root_);
template <typename Config, class Allocator> template <class Callback>
-void SplayTree<Config, Allocator>::ForEachNode(Callback* callback) {
+void SplayTree<Config, Allocator>::ForEachNode(Callback* callback,
+ Allocator allocator) {
// Pre-allocate some space for tiny trees.
List<Node*, Allocator> nodes_to_visit(10);
- if (root_ != NULL) nodes_to_visit.Add(root_);
+ if (root_ != NULL) nodes_to_visit.Add(root_, allocator);
int pos = 0;
while (pos < nodes_to_visit.length()) {
Node* node = nodes_to_visit[pos++];
- if (node->left() != NULL) nodes_to_visit.Add(node->left());
- if (node->right() != NULL) nodes_to_visit.Add(node->right());
+ if (node->left() != NULL) nodes_to_visit.Add(node->left(), allocator);
+ if (node->right() != NULL) nodes_to_visit.Add(node->right(), allocator);
callback->Call(node);
}
}
// Forward defined as
// template <typename Config, class Allocator = FreeStoreAllocationPolicy>
// class SplayTree;
-template <typename Config, class Allocator>
+template <typename Config, class AllocationPolicy>
class SplayTree {
public:
typedef typename Config::Key Key;
SplayTree() : root_(NULL) { }
~SplayTree();
- INLINE(void* operator new(size_t size)) {
- return Allocator::New(static_cast<int>(size));
+ INLINE(void* operator new(size_t size,
+ AllocationPolicy allocator = AllocationPolicy())) {
+ return allocator.New(static_cast<int>(size));
+ }
+ INLINE(void operator delete(void* p, size_t)) {
+ AllocationPolicy::Delete(p);
}
- INLINE(void operator delete(void* p, size_t)) { return Allocator::Delete(p); }
// Inserts the given key in this tree with the given value. Returns
// true if a node was inserted, otherwise false. If found the locator
// is enabled and provides access to the mapping for the key.
- bool Insert(const Key& key, Locator* locator);
+ bool Insert(const Key& key, Locator* locator,
+ AllocationPolicy allocator = AllocationPolicy());
// Looks up the key in this tree and returns true if it was found,
// otherwise false. If the node is found the locator is enabled and
left_(NULL),
right_(NULL) { }
- INLINE(void* operator new(size_t size)) {
- return Allocator::New(static_cast<int>(size));
+ INLINE(void* operator new(size_t size, AllocationPolicy allocator)) {
+ return allocator.New(static_cast<int>(size));
}
INLINE(void operator delete(void* p, size_t)) {
- return Allocator::Delete(p);
+ return AllocationPolicy::Delete(p);
}
Key key() { return key_; }
class NodeDeleter BASE_EMBEDDED {
public:
NodeDeleter() { }
- void Call(Node* node) { delete node; }
+ void Call(Node* node) { AllocationPolicy::Delete(node); }
private:
DISALLOW_COPY_AND_ASSIGN(NodeDeleter);
};
template <class Callback>
- void ForEachNode(Callback* callback);
+ void ForEachNode(Callback* callback,
+ AllocationPolicy allocator = AllocationPolicy());
Node* root_;
isolate->set_string_stream_current_security_token(NULL);
if (isolate->string_stream_debug_object_cache() == NULL) {
isolate->set_string_stream_debug_object_cache(
- new List<HeapObject*, PreallocatedStorage>(0));
+ new List<HeapObject*, PreallocatedStorageAllocationPolicy>(0));
}
isolate->string_stream_debug_object_cache()->Clear();
}
#include "log-inl.h"
#include "cpu-profiler-inl.h"
#include "handles-inl.h"
+#include "zone-inl.h"
namespace v8 {
namespace internal {
++jsframe_count;
}
}
- Translation translation(&translations_, frame_count, jsframe_count);
+ Translation translation(&translations_, frame_count, jsframe_count,
+ environment->zone());
WriteTranslation(environment, &translation);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
translation.index(),
(mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
- deoptimizations_.Add(environment);
+ deoptimizations_.Add(environment, environment->zone());
}
}
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));
}
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),
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();
}
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.
Register ToRegister(LOperand* op) const;
Safepoint::Kind expected_safepoint_kind_;
+ Zone* zone_;
+
class PushSafepointRegistersScope BASE_EMBEDDED {
public:
explicit PushSafepointRegistersScope(LCodeGen* codegen)
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;
: chunk_(NULL),
info_(info),
graph_(graph),
- zone_(graph->isolate()->zone()),
+ zone_(graph->zone()),
status_(UNUSED),
current_instruction_(NULL),
current_block_(NULL),
// Reset the root to avoid unneeded iteration over all tree nodes
// in the destructor. For a zone-allocated tree, nodes will be
// freed by the Zone.
- SplayTree<Config, ZoneListAllocationPolicy>::ResetRoot();
+ SplayTree<Config, ZoneAllocationPolicy>::ResetRoot();
}
return zone->New(static_cast<int>(size));
}
-
-inline void* ZoneListAllocationPolicy::New(int size) {
- return ZONE->New(size);
+inline void* ZoneAllocationPolicy::New(size_t size) {
+ if (zone_) {
+ return zone_->New(size);
+ } else {
+ return ZONE->New(size);
+ }
}
};
-// The ZoneListAllocationPolicy is used to specialize the GenericList
-// implementation to allocate ZoneLists and their elements in the
-// Zone.
-class ZoneListAllocationPolicy {
+// The ZoneAllocationPolicy is used to specialize generic data
+// structures to allocate themselves and their elements in the Zone.
+struct ZoneAllocationPolicy {
public:
- // Allocate 'size' bytes of memory in the zone.
- static void* New(int size);
+ explicit ZoneAllocationPolicy(Zone* zone = NULL) : zone_(zone) { }
+ INLINE(void* New(size_t size));
+ INLINE(static void Delete(void *pointer)) { }
- // De-allocation attempts are silently ignored.
- static void Delete(void* p) { }
+ private:
+ Zone* zone_;
};
// Zone. ZoneLists cannot be deleted individually; you can delete all
// objects in the Zone by calling Zone::DeleteAll().
template<typename T>
-class ZoneList: public List<T, ZoneListAllocationPolicy> {
+class ZoneList: public List<T, ZoneAllocationPolicy> {
public:
- INLINE(void* operator new(size_t size));
- INLINE(void* operator new(size_t size, Zone* zone));
-
// Construct a new ZoneList with the given capacity; the length is
// always zero. The capacity must be non-negative.
- explicit ZoneList(int capacity)
- : List<T, ZoneListAllocationPolicy>(capacity) { }
+ explicit ZoneList(int capacity, Zone* zone = NULL)
+ : List<T, ZoneAllocationPolicy>(capacity, ZoneAllocationPolicy(zone)) { }
+
+ INLINE(void* operator new(size_t size, Zone* zone));
+ INLINE(void* operator new(size_t size));
// Construct a new ZoneList by copying the elements of the given ZoneList.
- explicit ZoneList(const ZoneList<T>& other)
- : List<T, ZoneListAllocationPolicy>(other.length()) {
- AddAll(other);
+ explicit ZoneList(const ZoneList<T>& other, Zone* zone = NULL)
+ : List<T, ZoneAllocationPolicy>(other.length(),
+ ZoneAllocationPolicy(zone)) {
+ AddAll(other, ZoneAllocationPolicy(zone));
+ }
+
+ // We add some convenience wrappers so that we can pass in a Zone
+ // instead of a (less convenient) ZoneAllocationPolicy.
+ INLINE(void Add(const T& element, Zone* zone = NULL)) {
+ List<T, ZoneAllocationPolicy>::Add(element, ZoneAllocationPolicy(zone));
+ }
+ INLINE(void AddAll(const List<T, ZoneAllocationPolicy>& other,
+ Zone* zone = NULL)) {
+ List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
+ }
+ INLINE(void AddAll(const Vector<T>& other, Zone* zone = NULL)) {
+ List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
+ }
+ INLINE(void InsertAt(int index, const T& element, Zone* zone = NULL)) {
+ List<T, ZoneAllocationPolicy>::InsertAt(index, element,
+ ZoneAllocationPolicy(zone));
+ }
+ INLINE(Vector<T> AddBlock(T value, int count, Zone* zone = NULL)) {
+ return List<T, ZoneAllocationPolicy>::AddBlock(value, count,
+ ZoneAllocationPolicy(zone));
+ }
+ INLINE(void Allocate(int length, Zone* zone = NULL)) {
+ List<T, ZoneAllocationPolicy>::Allocate(length, ZoneAllocationPolicy(zone));
+ }
+ INLINE(void Initialize(int capacity, Zone* zone = NULL)) {
+ List<T, ZoneAllocationPolicy>::Initialize(capacity,
+ ZoneAllocationPolicy(zone));
}
void operator delete(void* pointer) { UNREACHABLE(); }
// different configurations of a concrete splay tree (see splay-tree.h).
// The tree itself and all its elements are allocated in the Zone.
template <typename Config>
-class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> {
+class ZoneSplayTree: public SplayTree<Config, ZoneAllocationPolicy> {
public:
ZoneSplayTree()
- : SplayTree<Config, ZoneListAllocationPolicy>() {}
+ : SplayTree<Config, ZoneAllocationPolicy>() {}
~ZoneSplayTree();
};
-typedef TemplateHashMapImpl<ZoneListAllocationPolicy> ZoneHashMap;
+typedef TemplateHashMapImpl<ZoneAllocationPolicy> ZoneHashMap;
} } // namespace v8::internal
// Use a testing allocator that clears memory before deletion.
class ZeroingAllocationPolicy {
public:
- static void* New(size_t size) {
+ void* New(size_t size) {
// Stash the size in the first word to use for Delete.
size_t true_size = size + sizeof(size_t);
size_t* result = reinterpret_cast<size_t*>(malloc(true_size));
FACTORY->NewStringFromUtf8(i::CStrVector(program.start())));
CHECK_EQ(source->length(), kProgramSize);
i::Handle<i::Script> script = FACTORY->NewScript(source);
- i::Parser parser(script, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL);
+ i::Parser parser(script, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL,
+ i::Isolate::Current()->zone());
i::CompilationInfo info(script);
info.MarkAsGlobal();
info.SetLanguageMode(source_data[i].language_mode);
i::Handle<i::Script> script = FACTORY->NewScript(source);
bool save_harmony_scoping = i::FLAG_harmony_scoping;
i::FLAG_harmony_scoping = harmony_scoping;
- i::Parser parser(script, flags, NULL, NULL);
+ i::Parser parser(script, flags, NULL, NULL, i::Isolate::Current()->zone());
i::CompilationInfo info(script);
info.MarkAsGlobal();
i::FunctionLiteral* function = parser.ParseProgram(&info);
multiline,
pattern,
sample_subject,
- is_ascii);
+ is_ascii,
+ isolate->zone());
return compile_data.node;
}