diff --git a/include/v8.h b/include/v8.h index a019c9d561..4bb3ad97c7 100644 --- a/include/v8.h +++ b/include/v8.h @@ -5398,7 +5398,7 @@ class Internals { static const int kNullValueRootIndex = 7; static const int kTrueValueRootIndex = 8; static const int kFalseValueRootIndex = 9; - static const int kEmptyStringRootIndex = 146; + static const int kEmptyStringRootIndex = 145; static const int kNodeClassIdOffset = 1 * kApiPointerSize; static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3; diff --git a/src/accessors.cc b/src/accessors.cc index cd4156468b..ba84c9a430 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -706,22 +706,21 @@ static MaybeObject* ConstructArgumentsObjectForInlinedFunction( int inlined_frame_index) { Isolate* isolate = inlined_function->GetIsolate(); Factory* factory = isolate->factory(); - SlotRefValueBuilder slot_refs( - frame, - inlined_frame_index, - inlined_function->shared()->formal_parameter_count()); - - int args_count = slot_refs.args_length(); + Vector args_slots = + SlotRef::ComputeSlotMappingForArguments( + frame, + inlined_frame_index, + inlined_function->shared()->formal_parameter_count()); + int args_count = args_slots.length(); Handle arguments = factory->NewArgumentsObject(inlined_function, args_count); Handle array = factory->NewFixedArray(args_count); - slot_refs.Prepare(isolate); for (int i = 0; i < args_count; ++i) { - Handle value = slot_refs.GetNext(isolate, 0); + Handle value = args_slots[i].GetValue(isolate); array->set(i, *value); } - slot_refs.Finish(isolate); arguments->set_elements(*array); + args_slots.Dispose(); // Return the freshly allocated arguments object. return *arguments; diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index 6d0ee47fbf..9e7e113ed9 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -773,11 +773,6 @@ void Deoptimizer::DoComputeOutputFrames() { } output_count_ = count; - Register fp_reg = JavaScriptFrame::fp_register(); - stack_fp_ = reinterpret_cast
( - input_->GetRegister(fp_reg.code()) + - has_alignment_padding_ * kPointerSize); - // Translate each output frame. for (int i = 0; i < count; ++i) { // Read the ast node id, function, and frame height for this output frame. @@ -1782,24 +1777,14 @@ Handle Deoptimizer::MaterializeNextHeapObject() { // Reuse the HeapNumber value directly as it is already properly // tagged and skip materializing the HeapNumber explicitly. Handle object = MaterializeNextValue(); - if (object_index < prev_materialized_count_) { - materialized_objects_->Add(Handle( - previously_materialized_objects_->get(object_index), isolate_)); - } else { - materialized_objects_->Add(object); - } + materialized_objects_->Add(object); materialization_value_index_ += kDoubleSize / kPointerSize - 1; break; } case JS_OBJECT_TYPE: { Handle object = isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED, false); - if (object_index < prev_materialized_count_) { - materialized_objects_->Add(Handle( - previously_materialized_objects_->get(object_index), isolate_)); - } else { - materialized_objects_->Add(object); - } + materialized_objects_->Add(object); Handle properties = MaterializeNextValue(); Handle elements = MaterializeNextValue(); object->set_properties(FixedArray::cast(*properties)); @@ -1813,12 +1798,7 @@ Handle Deoptimizer::MaterializeNextHeapObject() { case JS_ARRAY_TYPE: { Handle object = isolate_->factory()->NewJSArray(0, map->elements_kind()); - if (object_index < prev_materialized_count_) { - materialized_objects_->Add(Handle( - previously_materialized_objects_->get(object_index), isolate_)); - } else { - materialized_objects_->Add(object); - } + materialized_objects_->Add(object); Handle properties = MaterializeNextValue(); Handle elements = MaterializeNextValue(); Handle length = MaterializeNextValue(); @@ -1851,12 +1831,6 @@ Handle Deoptimizer::MaterializeNextValue() { void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { ASSERT_NE(DEBUGGER, bailout_type_); - MaterializedObjectStore* materialized_store = - isolate_->materialized_object_store(); - previously_materialized_objects_ = materialized_store->Get(stack_fp_); - prev_materialized_count_ = previously_materialized_objects_.is_null() ? - 0 : previously_materialized_objects_->length(); - // Walk all JavaScript output frames with the given frame iterator. for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { if (frame_index != 0) it->Advance(); @@ -1946,10 +1920,6 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { ASSERT(materialization_object_index_ == materialized_objects_->length()); ASSERT(materialization_value_index_ == materialized_values_->length()); } - - if (prev_materialized_count_ > 0) { - materialized_store->Remove(stack_fp_); - } } @@ -2978,11 +2948,12 @@ const char* Translation::StringFor(Opcode opcode) { // We can't intermix stack decoding and allocations because // deoptimization infrastracture is not GC safe. // Thus we build a temporary structure in malloced space. -SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument( - Translation::Opcode opcode, - TranslationIterator* iterator, - DeoptimizationInputData* data, - JavaScriptFrame* frame) { +SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator, + DeoptimizationInputData* data, + JavaScriptFrame* frame) { + Translation::Opcode opcode = + static_cast(iterator->Next()); + switch (opcode) { case Translation::BEGIN: case Translation::JS_FRAME: @@ -2993,18 +2964,12 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument( // Peeled off before getting here. break; - case Translation::DUPLICATED_OBJECT: { - return SlotRef::NewDuplicateObject(iterator->Next()); - } - + case Translation::DUPLICATED_OBJECT: case Translation::ARGUMENTS_OBJECT: + case Translation::CAPTURED_OBJECT: // This can be only emitted for local slots not for argument slots. break; - case Translation::CAPTURED_OBJECT: { - return SlotRef::NewDeferredObject(iterator->Next()); - } - case Translation::REGISTER: case Translation::INT32_REGISTER: case Translation::UINT32_REGISTER: @@ -3054,12 +3019,28 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument( } -SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, - int inlined_jsframe_index, - int formal_parameter_count) - : current_slot_(0), args_length_(-1), first_slot_index_(-1) { - DisallowHeapAllocation no_gc; +void SlotRef::ComputeSlotsForArguments(Vector* args_slots, + TranslationIterator* it, + DeoptimizationInputData* data, + JavaScriptFrame* frame) { + // Process the translation commands for the arguments. + // Skip the translation command for the receiver. + it->Skip(Translation::NumberOfOperandsFor( + static_cast(it->Next()))); + + // Compute slots for arguments. + for (int i = 0; i < args_slots->length(); ++i) { + (*args_slots)[i] = ComputeSlotForNextArgument(it, data, frame); + } +} + + +Vector SlotRef::ComputeSlotMappingForArguments( + JavaScriptFrame* frame, + int inlined_jsframe_index, + int formal_parameter_count) { + DisallowHeapAllocation no_gc; int deopt_index = Safepoint::kNoDeoptimizationIndex; DeoptimizationInputData* data = static_cast(frame)->GetDeoptimizationData(&deopt_index); @@ -3068,18 +3049,12 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, Translation::Opcode opcode = static_cast(it.Next()); ASSERT(opcode == Translation::BEGIN); it.Next(); // Drop frame count. - - stack_frame_id_ = frame->fp(); - int jsframe_count = it.Next(); USE(jsframe_count); ASSERT(jsframe_count > inlined_jsframe_index); int jsframes_to_skip = inlined_jsframe_index; - int number_of_slots = -1; // Number of slots inside our frame (yet unknown) - bool should_deopt = false; - while (number_of_slots != 0) { + while (true) { opcode = static_cast(it.Next()); - bool processed = false; if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) { if (jsframes_to_skip == 0) { ASSERT(Translation::NumberOfOperandsFor(opcode) == 2); @@ -3087,336 +3062,36 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, it.Skip(1); // literal id int height = it.Next(); - // Skip the translation command for the receiver. - it.Skip(Translation::NumberOfOperandsFor( - static_cast(it.Next()))); - // We reached the arguments adaptor frame corresponding to the // inlined function in question. Number of arguments is height - 1. - first_slot_index_ = slot_refs_.length(); - args_length_ = height - 1; - number_of_slots = height - 1; - processed = true; + Vector args_slots = + Vector::New(height - 1); // Minus receiver. + ComputeSlotsForArguments(&args_slots, &it, data, frame); + return args_slots; } } else if (opcode == Translation::JS_FRAME) { if (jsframes_to_skip == 0) { // Skip over operands to advance to the next opcode. it.Skip(Translation::NumberOfOperandsFor(opcode)); - // Skip the translation command for the receiver. - it.Skip(Translation::NumberOfOperandsFor( - static_cast(it.Next()))); - // We reached the frame corresponding to the inlined function // in question. Process the translation commands for the // arguments. Number of arguments is equal to the number of // format parameter count. - first_slot_index_ = slot_refs_.length(); - args_length_ = formal_parameter_count; - number_of_slots = formal_parameter_count; - processed = true; + Vector args_slots = + Vector::New(formal_parameter_count); + ComputeSlotsForArguments(&args_slots, &it, data, frame); + return args_slots; } jsframes_to_skip--; - } else if (opcode != Translation::BEGIN && - opcode != Translation::CONSTRUCT_STUB_FRAME) { - slot_refs_.Add(ComputeSlotForNextArgument(opcode, &it, data, frame)); - - if (first_slot_index_ >= 0) { - // We have found the beginning of our frame -> make sure we count - // the nested slots of captured objects - number_of_slots--; - SlotRef& slot = slot_refs_.last(); - if (slot.Representation() == SlotRef::DEFERRED_OBJECT) { - number_of_slots += slot.DeferredObjectLength(); - } - if (slot.Representation() == SlotRef::DEFERRED_OBJECT || - slot.Representation() == SlotRef::DUPLICATE_OBJECT) { - should_deopt = true; - } - } - - processed = true; - } - if (!processed) { - // Skip over operands to advance to the next opcode. - it.Skip(Translation::NumberOfOperandsFor(opcode)); - } - } - if (should_deopt) { - List functions(2); - frame->GetFunctions(&functions); - Deoptimizer::DeoptimizeFunction(functions[0]); - } -} - - -Handle SlotRef::GetValue(Isolate* isolate) { - switch (representation_) { - case TAGGED: - return Handle(Memory::Object_at(addr_), isolate); - - case INT32: { - int value = Memory::int32_at(addr_); - if (Smi::IsValid(value)) { - return Handle(Smi::FromInt(value), isolate); - } else { - return isolate->factory()->NewNumberFromInt(value); - } } - case UINT32: { - uint32_t value = Memory::uint32_at(addr_); - if (value <= static_cast(Smi::kMaxValue)) { - return Handle(Smi::FromInt(static_cast(value)), isolate); - } else { - return isolate->factory()->NewNumber(static_cast(value)); - } - } - - case DOUBLE: { - double value = read_double_value(addr_); - return isolate->factory()->NewNumber(value); - } - - case LITERAL: - return literal_; - - default: - UNREACHABLE(); - return Handle::null(); - } -} - - -void SlotRefValueBuilder::Prepare(Isolate* isolate) { - MaterializedObjectStore* materialized_store = - isolate->materialized_object_store(); - previously_materialized_objects_ = materialized_store->Get(stack_frame_id_); - prev_materialized_count_ = previously_materialized_objects_.is_null() - ? 0 : previously_materialized_objects_->length(); - - // Skip any materialized objects of the inlined "parent" frames. - // (Note that we still need to materialize them because they might be - // referred to as duplicated objects.) - while (current_slot_ < first_slot_index_) { - GetNext(isolate, 0); - } - ASSERT(current_slot_ == first_slot_index_); -} - - -Handle SlotRefValueBuilder::GetPreviouslyMaterialized( - Isolate* isolate, int length) { - int object_index = materialized_objects_.length(); - Handle return_value = Handle( - previously_materialized_objects_->get(object_index), isolate); - materialized_objects_.Add(return_value); - - // Now need to skip all nested objects (and possibly read them from - // the materialization store, too) - for (int i = 0; i < length; i++) { - SlotRef& slot = slot_refs_[current_slot_]; - current_slot_++; - - // For nested deferred objects, we need to read its properties - if (slot.Representation() == SlotRef::DEFERRED_OBJECT) { - length += slot.DeferredObjectLength(); - } - - // For nested deferred and duplicate objects, we need to put them into - // our materialization array - if (slot.Representation() == SlotRef::DEFERRED_OBJECT || - slot.Representation() == SlotRef::DUPLICATE_OBJECT) { - int nested_object_index = materialized_objects_.length(); - Handle nested_object = Handle( - previously_materialized_objects_->get(nested_object_index), - isolate); - materialized_objects_.Add(nested_object); - } - } - - return return_value; -} - - -Handle SlotRefValueBuilder::GetNext(Isolate* isolate, int lvl) { - SlotRef& slot = slot_refs_[current_slot_]; - current_slot_++; - switch (slot.Representation()) { - case SlotRef::TAGGED: - case SlotRef::INT32: - case SlotRef::UINT32: - case SlotRef::DOUBLE: - case SlotRef::LITERAL: { - return slot.GetValue(isolate); - } - case SlotRef::DEFERRED_OBJECT: { - int length = slot.DeferredObjectLength(); - ASSERT(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL || - slot_refs_[current_slot_].Representation() == SlotRef::TAGGED); - - int object_index = materialized_objects_.length(); - if (object_index < prev_materialized_count_) { - return GetPreviouslyMaterialized(isolate, length); - } - - Handle map_object = slot_refs_[current_slot_].GetValue(isolate); - Handle map = Map::GeneralizeAllFieldRepresentations( - Handle::cast(map_object), Representation::Tagged()); - current_slot_++; - // TODO(jarin) this should be unified with the code in - // Deoptimizer::MaterializeNextHeapObject() - switch (map->instance_type()) { - case HEAP_NUMBER_TYPE: { - // Reuse the HeapNumber value directly as it is already properly - // tagged and skip materializing the HeapNumber explicitly. - Handle object = GetNext(isolate, lvl + 1); - materialized_objects_.Add(object); - return object; - } - case JS_OBJECT_TYPE: { - Handle object = - isolate->factory()->NewJSObjectFromMap(map, NOT_TENURED, false); - materialized_objects_.Add(object); - Handle properties = GetNext(isolate, lvl + 1); - Handle elements = GetNext(isolate, lvl + 1); - object->set_properties(FixedArray::cast(*properties)); - object->set_elements(FixedArrayBase::cast(*elements)); - for (int i = 0; i < length - 3; ++i) { - Handle value = GetNext(isolate, lvl + 1); - object->FastPropertyAtPut(i, *value); - } - return object; - } - case JS_ARRAY_TYPE: { - Handle object = - isolate->factory()->NewJSArray(0, map->elements_kind()); - materialized_objects_.Add(object); - Handle properties = GetNext(isolate, lvl + 1); - Handle elements = GetNext(isolate, lvl + 1); - Handle length = GetNext(isolate, lvl + 1); - object->set_properties(FixedArray::cast(*properties)); - object->set_elements(FixedArrayBase::cast(*elements)); - object->set_length(*length); - return object; - } - default: - PrintF(stderr, - "[couldn't handle instance type %d]\n", map->instance_type()); - UNREACHABLE(); - break; - } - UNREACHABLE(); - } - - case SlotRef::DUPLICATE_OBJECT: { - int object_index = slot.DuplicateObjectId(); - Handle object = materialized_objects_[object_index]; - materialized_objects_.Add(object); - return object; - } - default: - UNREACHABLE(); - break; + // Skip over operands to advance to the next opcode. + it.Skip(Translation::NumberOfOperandsFor(opcode)); } UNREACHABLE(); - return Handle::null(); -} - - -void SlotRefValueBuilder::Finish(Isolate* isolate) { - // We should have processed all slot - ASSERT(slot_refs_.length() == current_slot_); - - if (materialized_objects_.length() > prev_materialized_count_) { - // We have materialized some new objects, so we have to store them - // to prevent duplicate materialization - Handle array = isolate->factory()->NewFixedArray( - materialized_objects_.length()); - for (int i = 0; i < materialized_objects_.length(); i++) { - array->set(i, *(materialized_objects_.at(i))); - } - isolate->materialized_object_store()->Set(stack_frame_id_, array); - } -} - - -Handle MaterializedObjectStore::Get(Address fp) { - int index = StackIdToIndex(fp); - if (index == -1) { - return Handle::null(); - } - Handle array = GetStackEntries(); - ASSERT(array->length() > index); - return Handle::cast(Handle(array->get(index), - isolate())); -} - - -void MaterializedObjectStore::Set(Address fp, - Handle materialized_objects) { - int index = StackIdToIndex(fp); - if (index == -1) { - index = frame_fps_.length(); - frame_fps_.Add(fp); - } - - Handle array = EnsureStackEntries(index + 1); - array->set(index, *materialized_objects); -} - - -void MaterializedObjectStore::Remove(Address fp) { - int index = StackIdToIndex(fp); - ASSERT(index >= 0); - - frame_fps_.Remove(index); - Handle array = GetStackEntries(); - ASSERT(array->length() > index); - for (int i = index; i < frame_fps_.length(); i++) { - array->set(i, array->get(i + 1)); - } - array->set(frame_fps_.length(), isolate()->heap()->undefined_value()); -} - - -int MaterializedObjectStore::StackIdToIndex(Address fp) { - for (int i = 0; i < frame_fps_.length(); i++) { - if (frame_fps_[i] == fp) { - return i; - } - } - return -1; -} - - -Handle MaterializedObjectStore::GetStackEntries() { - return Handle(isolate()->heap()->materialized_objects()); -} - - -Handle MaterializedObjectStore::EnsureStackEntries(int length) { - Handle array = GetStackEntries(); - if (array->length() >= length) { - return array; - } - - int new_length = length > 10 ? length : 10; - if (new_length < 2 * array->length()) { - new_length = 2 * array->length(); - } - - Handle new_array = - isolate()->factory()->NewFixedArray(new_length, TENURED); - for (int i = 0; i < array->length(); i++) { - new_array->set(i, array->get(i)); - } - for (int i = array->length(); i < length; i++) { - new_array->set(i, isolate()->heap()->undefined_value()); - } - isolate()->heap()->public_set_materialized_objects(*new_array); - return new_array; + return Vector(); } #ifdef ENABLE_DEBUGGER_SUPPORT diff --git a/src/deoptimizer.h b/src/deoptimizer.h index 806433c6f3..aace220867 100644 --- a/src/deoptimizer.h +++ b/src/deoptimizer.h @@ -435,11 +435,6 @@ class Deoptimizer : public Malloced { List deferred_objects_; List > deferred_heap_numbers_; - // Key for lookup of previously materialized objects - Address stack_fp_; - Handle previously_materialized_objects_; - int prev_materialized_count_; - // Output frame information. Only used during heap object materialization. List > jsframe_functions_; List jsframe_has_adapted_arguments_; @@ -788,13 +783,7 @@ class SlotRef BASE_EMBEDDED { INT32, UINT32, DOUBLE, - LITERAL, - DEFERRED_OBJECT, // Object captured by the escape analysis. - // The number of nested objects can be obtained - // with the DeferredObjectLength() method - // (the SlotRefs of the nested objects follow - // this SlotRef in the depth-first order.) - DUPLICATE_OBJECT // Duplicated object of a deferred object. + LITERAL }; SlotRef() @@ -806,66 +795,52 @@ class SlotRef BASE_EMBEDDED { SlotRef(Isolate* isolate, Object* literal) : literal_(literal, isolate), representation_(LITERAL) { } - static SlotRef NewDeferredObject(int length) { - SlotRef slot; - slot.representation_ = DEFERRED_OBJECT; - slot.deferred_object_length_ = length; - return slot; + Handle GetValue(Isolate* isolate) { + switch (representation_) { + case TAGGED: + return Handle(Memory::Object_at(addr_), isolate); + + case INT32: { + int value = Memory::int32_at(addr_); + if (Smi::IsValid(value)) { + return Handle(Smi::FromInt(value), isolate); + } else { + return isolate->factory()->NewNumberFromInt(value); + } + } + + case UINT32: { + uint32_t value = Memory::uint32_at(addr_); + if (value <= static_cast(Smi::kMaxValue)) { + return Handle(Smi::FromInt(static_cast(value)), isolate); + } else { + return isolate->factory()->NewNumber(static_cast(value)); + } + } + + case DOUBLE: { + double value = read_double_value(addr_); + return isolate->factory()->NewNumber(value); + } + + case LITERAL: + return literal_; + + default: + UNREACHABLE(); + return Handle::null(); + } } - SlotRepresentation Representation() { return representation_; } - - static SlotRef NewDuplicateObject(int id) { - SlotRef slot; - slot.representation_ = DUPLICATE_OBJECT; - slot.duplicate_object_id_ = id; - return slot; - } - - int DeferredObjectLength() { return deferred_object_length_; } - - int DuplicateObjectId() { return duplicate_object_id_; } - - Handle GetValue(Isolate* isolate); + static Vector ComputeSlotMappingForArguments( + JavaScriptFrame* frame, + int inlined_frame_index, + int formal_parameter_count); private: Address addr_; Handle literal_; SlotRepresentation representation_; - int deferred_object_length_; - int duplicate_object_id_; -}; - -class SlotRefValueBuilder BASE_EMBEDDED { - public: - SlotRefValueBuilder( - JavaScriptFrame* frame, - int inlined_frame_index, - int formal_parameter_count); - - void Prepare(Isolate* isolate); - Handle GetNext(Isolate* isolate, int level); - void Finish(Isolate* isolate); - - int args_length() { return args_length_; } - - private: - List > materialized_objects_; - Handle previously_materialized_objects_; - int prev_materialized_count_; - Address stack_frame_id_; - List slot_refs_; - int current_slot_; - int args_length_; - int first_slot_index_; - - static SlotRef ComputeSlotForNextArgument( - Translation::Opcode opcode, - TranslationIterator* iterator, - DeoptimizationInputData* data, - JavaScriptFrame* frame); - - Handle GetPreviouslyMaterialized(Isolate* isolate, int length); static Address SlotAddress(JavaScriptFrame* frame, int slot_index) { if (slot_index >= 0) { @@ -877,27 +852,15 @@ class SlotRefValueBuilder BASE_EMBEDDED { } } - Handle GetDeferredObject(Isolate* isolate); -}; + static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator, + DeoptimizationInputData* data, + JavaScriptFrame* frame); -class MaterializedObjectStore { - public: - explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) { - } - - Handle Get(Address fp); - void Set(Address fp, Handle materialized_objects); - void Remove(Address fp); - - private: - Isolate* isolate() { return isolate_; } - Handle GetStackEntries(); - Handle EnsureStackEntries(int size); - - int StackIdToIndex(Address fp); - - Isolate* isolate_; - List
frame_fps_; + static void ComputeSlotsForArguments( + Vector* args_slots, + TranslationIterator* iterator, + DeoptimizationInputData* data, + JavaScriptFrame* frame); }; diff --git a/src/heap.cc b/src/heap.cc index 5bae585476..862e2eaa24 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -3293,11 +3293,6 @@ bool Heap::CreateInitialObjects() { Symbol::cast(obj)->set_is_private(true); set_observed_symbol(Symbol::cast(obj)); - { MaybeObject* maybe_obj = AllocateFixedArray(0, TENURED); - if (!maybe_obj->ToObject(&obj)) return false; - } - set_materialized_objects(FixedArray::cast(obj)); - // Handling of script id generation is in Factory::NewScript. set_last_script_id(Smi::FromInt(v8::Script::kNoScriptId)); diff --git a/src/heap.h b/src/heap.h index 2a95082297..c9101bea9f 100644 --- a/src/heap.h +++ b/src/heap.h @@ -201,8 +201,7 @@ namespace internal { V(Symbol, elements_transition_symbol, ElementsTransitionSymbol) \ V(SeededNumberDictionary, empty_slow_element_dictionary, \ EmptySlowElementDictionary) \ - V(Symbol, observed_symbol, ObservedSymbol) \ - V(FixedArray, materialized_objects, MaterializedObjects) + V(Symbol, observed_symbol, ObservedSymbol) #define ROOT_LIST(V) \ STRONG_ROOT_LIST(V) \ @@ -1368,10 +1367,6 @@ class Heap { roots_[kStoreBufferTopRootIndex] = reinterpret_cast(top); } - void public_set_materialized_objects(FixedArray* objects) { - roots_[kMaterializedObjectsRootIndex] = objects; - } - // Generated code can embed this address to get access to the roots. Object** roots_array_start() { return roots_; } diff --git a/src/isolate.cc b/src/isolate.cc index 3983c48858..c5479ebf08 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -1529,7 +1529,6 @@ Isolate::Isolate() stats_table_(NULL), stub_cache_(NULL), deoptimizer_data_(NULL), - materialized_object_store_(NULL), capture_stack_trace_for_uncaught_exceptions_(false), stack_trace_for_uncaught_exceptions_frame_limit_(0), stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview), @@ -1778,9 +1777,6 @@ Isolate::~Isolate() { delete stats_table_; stats_table_ = NULL; - delete materialized_object_store_; - materialized_object_store_ = NULL; - delete logger_; logger_ = NULL; @@ -1951,7 +1947,6 @@ bool Isolate::Init(Deserializer* des) { bootstrapper_ = new Bootstrapper(this); handle_scope_implementer_ = new HandleScopeImplementer(this); stub_cache_ = new StubCache(this); - materialized_object_store_ = new MaterializedObjectStore(this); regexp_stack_ = new RegExpStack(); regexp_stack_->isolate_ = this; date_cache_ = new DateCache(); diff --git a/src/isolate.h b/src/isolate.h index 4dad86b1a8..5956baad88 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -51,13 +51,12 @@ namespace v8 { namespace internal { class Bootstrapper; -struct CallInterfaceDescriptor; class CodeGenerator; class CodeRange; struct CodeStubInterfaceDescriptor; +struct CallInterfaceDescriptor; class CodeTracer; class CompilationCache; -class ConsStringIteratorOp; class ContextSlotCache; class Counters; class CpuFeatures; @@ -74,19 +73,19 @@ class HeapProfiler; class HStatistics; class HTracer; class InlineRuntimeFunctionsTable; -class InnerPointerToCodeCache; -class MaterializedObjectStore; class NoAllocationStringAllocator; +class InnerPointerToCodeCache; class RandomNumberGenerator; class RegExpStack; class SaveContext; +class UnicodeCache; +class ConsStringIteratorOp; class StringTracker; class StubCache; class SweeperThread; class ThreadManager; class ThreadState; class ThreadVisitor; // Defined in v8threads.h -class UnicodeCache; template class VMState; // 'void function pointer', used to roundtrip the @@ -870,9 +869,6 @@ class Isolate { StubCache* stub_cache() { return stub_cache_; } DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; } ThreadLocalTop* thread_local_top() { return &thread_local_top_; } - MaterializedObjectStore* materialized_object_store() { - return materialized_object_store_; - } MemoryAllocator* memory_allocator() { return memory_allocator_; @@ -1279,7 +1275,6 @@ class Isolate { StatsTable* stats_table_; StubCache* stub_cache_; DeoptimizerData* deoptimizer_data_; - MaterializedObjectStore* materialized_object_store_; ThreadLocalTop thread_local_top_; bool capture_stack_trace_for_uncaught_exceptions_; int stack_trace_for_uncaught_exceptions_frame_limit_; diff --git a/src/lithium.cc b/src/lithium.cc index b4f96290c7..b2fb4ead7c 100644 --- a/src/lithium.cc +++ b/src/lithium.cc @@ -532,16 +532,16 @@ LEnvironment* LChunkBuilderBase::CreateEnvironment( // We are building three lists here: // // 1. In the result->object_mapping_ list (added to by the -// LEnvironment::Add*Object methods), we store the lengths (number -// of fields) of the captured objects in depth-first traversal order, or -// in case of duplicated objects, we store the index to the duplicate object -// (with a tag to differentiate between captured and duplicated objects). +// LEnvironment::Add*Object methods), we store the lengths (number +// of fields) of the captured objects in depth-first traversal order, or +// in case of duplicated objects, we store the index to the duplicate object +// (with a tag to differentiate between captured and duplicated objects). // // 2. The object fields are stored in the result->values_ list -// (added to by the LEnvironment.AddValue method) sequentially as lists -// of fields with holes for nested objects (the holes will be expanded -// later by LCodegen::AddToTranslation according to the -// LEnvironment.object_mapping_ list). +// (added to by the LEnvironment.AddValue method) sequentially as lists +// of fields with holes for nested objects (the holes will be expanded +// later by LCodegen::AddToTranslation according to the +// LEnvironment.object_mapping_ list). // // 3. The auxiliary objects_to_materialize array stores the hydrogen values // in the same order as result->object_mapping_ list. This is used diff --git a/src/runtime.cc b/src/runtime.cc index 34423515e1..a2bc186d61 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -8049,22 +8049,23 @@ static SmartArrayPointer > GetCallerArguments( if (functions.length() > 1) { int inlined_jsframe_index = functions.length() - 1; JSFunction* inlined_function = functions[inlined_jsframe_index]; - SlotRefValueBuilder slot_refs( - frame, - inlined_jsframe_index, - inlined_function->shared()->formal_parameter_count()); + Vector args_slots = + SlotRef::ComputeSlotMappingForArguments( + frame, + inlined_jsframe_index, + inlined_function->shared()->formal_parameter_count()); - int args_count = slot_refs.args_length(); + int args_count = args_slots.length(); *total_argc = prefix_argc + args_count; SmartArrayPointer > param_data( NewArray >(*total_argc)); - slot_refs.Prepare(isolate); for (int i = 0; i < args_count; i++) { - Handle val = slot_refs.GetNext(isolate, 0); + Handle val = args_slots[i].GetValue(isolate); param_data[prefix_argc + i] = val; } - slot_refs.Finish(isolate); + + args_slots.Dispose(); return param_data; } else { diff --git a/test/mjsunit/compiler/escape-analysis-arguments.js b/test/mjsunit/compiler/escape-analysis-arguments.js deleted file mode 100644 index bdab182fed..0000000000 --- a/test/mjsunit/compiler/escape-analysis-arguments.js +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2013 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax --use-escape-analysis --expose-gc - - -// Simple test of capture -(function testCapturedArguments() { - function h() { - return g.arguments[0]; - } - - function g(x) { - return h(); - } - - function f() { - var l = { y : { z : 4 }, x : 2 } - var r = g(l); - assertEquals(2, r.x); - assertEquals(2, l.x); - l.x = 3; - l.y.z = 5; - // Test that the arguments object is properly - // aliased - assertEquals(3, r.x); - assertEquals(3, l.x); - assertEquals(5, r.y.z); - } - - f(); f(); f(); - %OptimizeFunctionOnNextCall(f); - f(); -})(); - - -// Get the arguments object twice, test aliasing -(function testTwoCapturedArguments() { - function h() { - return g.arguments[0]; - } - - function i() { - return g.arguments[0]; - } - - function g(x) { - return {h : h() , i : i()}; - } - - function f() { - var l = { y : { z : 4 }, x : 2 } - var r = g(l); - assertEquals(2, r.h.x) - l.y.z = 3; - assertEquals(3, r.h.y.z); - assertEquals(3, r.i.y.z); - } - - f(); f(); f(); - %OptimizeFunctionOnNextCall(f); - f(); -})(); - - -// Nested arguments object test -(function testTwoCapturedArgumentsNested() { - function i() { - return { gx : g.arguments[0], hx : h.arguments[0] }; - } - - function h(x) { - return i(); - } - - function g(x) { - return h(x.y); - } - - function f() { - var l = { y : { z : 4 }, x : 2 } - var r = g(l); - assertEquals(2, r.gx.x) - assertEquals(4, r.gx.y.z) - assertEquals(4, r.hx.z) - l.y.z = 3; - assertEquals(3, r.gx.y.z) - assertEquals(3, r.hx.z) - assertEquals(3, l.y.z) - } - - f(); f(); f(); - %OptimizeFunctionOnNextCall(f); - f(); f(); - %OptimizeFunctionOnNextCall(f); - f(); f(); -})(); - - -// Nested arguments object test with different inlining -(function testTwoCapturedArgumentsNested2() { - function i() { - return { gx : g.arguments[0], hx : h.arguments[0] }; - } - - function h(x) { - return i(); - } - - function g(x) { - return h(x.y); - } - - function f() { - var l = { y : { z : 4 }, x : 2 } - var r = g(l); - assertEquals(2, r.gx.x) - assertEquals(4, r.gx.y.z) - assertEquals(4, r.hx.z) - l.y.z = 3; - assertEquals(3, r.gx.y.z) - assertEquals(3, r.hx.z) - assertEquals(3, l.y.z) - } - - %NeverOptimizeFunction(i); - f(); f(); f(); - %OptimizeFunctionOnNextCall(f); - f(); f(); - %OptimizeFunctionOnNextCall(f); - f(); f(); -})(); - - -// Multiple captured argument test -(function testTwoArgumentsCapture() { - function h() { - return { a : g.arguments[1], b : g.arguments[0] }; - } - - function g(x, y) { - return h(); - } - - function f() { - var l = { y : { z : 4 }, x : 2 } - var k = { t : { u : 3 } }; - var r = g(k, l); - assertEquals(2, r.a.x) - assertEquals(4, r.a.y.z) - assertEquals(3, r.b.t.u) - l.y.z = 6; - r.b.t.u = 7; - assertEquals(6, r.a.y.z) - assertEquals(7, k.t.u) - } - - f(); f(); f(); - %OptimizeFunctionOnNextCall(f); - f(); f(); - %OptimizeFunctionOnNextCall(f); - f(); f(); -})();