| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 5b9d02747034e0a63a47310ed28a2c9e5ec69d29..c78fcb1587b192766c913cda9b59efd8467cf0d2 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -1539,14 +1539,15 @@ HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
|
|
|
|
|
| HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) {
|
| - HValue* half_old_capacity = Add<HShr>(old_capacity, graph_->GetConstant1());
|
| + HValue* half_old_capacity = AddUncasted<HShr>(old_capacity,
|
| + graph_->GetConstant1());
|
|
|
| - HValue* new_capacity = Add<HAdd>(half_old_capacity, old_capacity);
|
| + HValue* new_capacity = AddUncasted<HAdd>(half_old_capacity, old_capacity);
|
| new_capacity->ClearFlag(HValue::kCanOverflow);
|
|
|
| HValue* min_growth = Add<HConstant>(16);
|
|
|
| - new_capacity = Add<HAdd>(new_capacity, min_growth);
|
| + new_capacity = AddUncasted<HAdd>(new_capacity, min_growth);
|
| new_capacity->ClearFlag(HValue::kCanOverflow);
|
|
|
| return new_capacity;
|
| @@ -1710,22 +1711,12 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
|
| if (mode == TRACK_ALLOCATION_SITE) {
|
| size += AllocationMemento::kSize;
|
| }
|
| - int elems_offset = size;
|
| - InstanceType instance_type = IsFastDoubleElementsKind(kind) ?
|
| - FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE;
|
| - if (length > 0) {
|
| - size += IsFastDoubleElementsKind(kind)
|
| - ? FixedDoubleArray::SizeFor(length)
|
| - : FixedArray::SizeFor(length);
|
| - }
|
|
|
| - // Allocate both the JS array and the elements array in one big
|
| - // allocation. This avoids multiple limit checks.
|
| HValue* size_in_bytes = Add<HConstant>(size);
|
| HInstruction* object = Add<HAllocate>(size_in_bytes,
|
| HType::JSObject(),
|
| NOT_TENURED,
|
| - instance_type);
|
| + JS_OBJECT_TYPE);
|
|
|
| // Copy the JS array part.
|
| for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
|
| @@ -1742,10 +1733,17 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
|
| }
|
|
|
| if (length > 0) {
|
| - // Get hold of the elements array of the boilerplate and setup the
|
| - // elements pointer in the resulting object.
|
| HValue* boilerplate_elements = AddLoadElements(boilerplate);
|
| - HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
|
| + HValue* object_elements;
|
| + if (IsFastDoubleElementsKind(kind)) {
|
| + HValue* elems_size = Add<HConstant>(FixedDoubleArray::SizeFor(length));
|
| + object_elements = Add<HAllocate>(elems_size, HType::JSArray(),
|
| + NOT_TENURED, FIXED_DOUBLE_ARRAY_TYPE);
|
| + } else {
|
| + HValue* elems_size = Add<HConstant>(FixedArray::SizeFor(length));
|
| + object_elements = Add<HAllocate>(elems_size, HType::JSArray(),
|
| + NOT_TENURED, FIXED_ARRAY_TYPE);
|
| + }
|
| Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
|
| object_elements);
|
|
|
| @@ -2044,7 +2042,7 @@ HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info)
|
| // constructor for the initial state relies on function_state_ == NULL
|
| // to know it's the initial state.
|
| function_state_= &initial_function_state_;
|
| - InitializeAstVisitor();
|
| + InitializeAstVisitor(info->isolate());
|
| }
|
|
|
|
|
| @@ -2773,16 +2771,6 @@ void TestContext::BuildBranch(HValue* value) {
|
| if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
|
| builder->Bailout(kArgumentsObjectValueInATestContext);
|
| }
|
| - if (value->IsConstant()) {
|
| - HConstant* constant_value = HConstant::cast(value);
|
| - if (constant_value->BooleanValue()) {
|
| - builder->current_block()->Goto(if_true(), builder->function_state());
|
| - } else {
|
| - builder->current_block()->Goto(if_false(), builder->function_state());
|
| - }
|
| - builder->set_current_block(NULL);
|
| - return;
|
| - }
|
| HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
|
| HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
|
| ToBooleanStub::Types expected(condition()->to_boolean_types());
|
| @@ -3127,7 +3115,9 @@ void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
|
|
|
| void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
|
| for (int i = 0; i < statements->length(); i++) {
|
| - CHECK_ALIVE(Visit(statements->at(i)));
|
| + Statement* stmt = statements->at(i);
|
| + CHECK_ALIVE(Visit(stmt));
|
| + if (stmt->IsJump()) break;
|
| }
|
| }
|
|
|
| @@ -4101,9 +4091,7 @@ static bool LookupSetter(Handle<Map> map,
|
| // size of all objects that are part of the graph.
|
| static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| int max_depth,
|
| - int* max_properties,
|
| - int* data_size,
|
| - int* pointer_size) {
|
| + int* max_properties) {
|
| if (boilerplate->map()->is_deprecated()) {
|
| Handle<Object> result = JSObject::TryMigrateInstance(boilerplate);
|
| if (result->IsSmi()) return false;
|
| @@ -4116,9 +4104,7 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| Handle<FixedArrayBase> elements(boilerplate->elements());
|
| if (elements->length() > 0 &&
|
| elements->map() != isolate->heap()->fixed_cow_array_map()) {
|
| - if (boilerplate->HasFastDoubleElements()) {
|
| - *data_size += FixedDoubleArray::SizeFor(elements->length());
|
| - } else if (boilerplate->HasFastObjectElements()) {
|
| + if (boilerplate->HasFastObjectElements()) {
|
| Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
|
| int length = elements->length();
|
| for (int i = 0; i < length; i++) {
|
| @@ -4128,15 +4114,12 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
| if (!IsFastLiteral(value_object,
|
| max_depth - 1,
|
| - max_properties,
|
| - data_size,
|
| - pointer_size)) {
|
| + max_properties)) {
|
| return false;
|
| }
|
| }
|
| }
|
| - *pointer_size += FixedArray::SizeFor(length);
|
| - } else {
|
| + } else if (!boilerplate->HasFastDoubleElements()) {
|
| return false;
|
| }
|
| }
|
| @@ -4151,7 +4134,6 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| for (int i = 0; i < limit; i++) {
|
| PropertyDetails details = descriptors->GetDetails(i);
|
| if (details.type() != FIELD) continue;
|
| - Representation representation = details.representation();
|
| int index = descriptors->GetFieldIndex(i);
|
| if ((*max_properties)-- == 0) return false;
|
| Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate);
|
| @@ -4159,18 +4141,12 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
| if (!IsFastLiteral(value_object,
|
| max_depth - 1,
|
| - max_properties,
|
| - data_size,
|
| - pointer_size)) {
|
| + max_properties)) {
|
| return false;
|
| }
|
| - } else if (representation.IsDouble()) {
|
| - *data_size += HeapNumber::kSize;
|
| }
|
| }
|
| }
|
| -
|
| - *pointer_size += boilerplate->map()->instance_size();
|
| return true;
|
| }
|
|
|
| @@ -4180,32 +4156,21 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
|
| ASSERT(current_block() != NULL);
|
| ASSERT(current_block()->HasPredecessor());
|
| Handle<JSFunction> closure = function_state()->compilation_info()->closure();
|
| - HValue* context = environment()->context();
|
| HInstruction* literal;
|
|
|
| // Check whether to use fast or slow deep-copying for boilerplate.
|
| - int data_size = 0;
|
| - int pointer_size = 0;
|
| int max_properties = kMaxFastLiteralProperties;
|
| - Handle<Object> original_boilerplate(closure->literals()->get(
|
| + Handle<Object> boilerplate(closure->literals()->get(
|
| expr->literal_index()), isolate());
|
| - if (original_boilerplate->IsJSObject() &&
|
| - IsFastLiteral(Handle<JSObject>::cast(original_boilerplate),
|
| + if (boilerplate->IsJSObject() &&
|
| + IsFastLiteral(Handle<JSObject>::cast(boilerplate),
|
| kMaxFastLiteralDepth,
|
| - &max_properties,
|
| - &data_size,
|
| - &pointer_size)) {
|
| - Handle<JSObject> original_boilerplate_object =
|
| - Handle<JSObject>::cast(original_boilerplate);
|
| + &max_properties)) {
|
| Handle<JSObject> boilerplate_object =
|
| - DeepCopy(original_boilerplate_object);
|
| + Handle<JSObject>::cast(boilerplate);
|
|
|
| - literal = BuildFastLiteral(context,
|
| - boilerplate_object,
|
| - original_boilerplate_object,
|
| + literal = BuildFastLiteral(boilerplate_object,
|
| Handle<Object>::null(),
|
| - data_size,
|
| - pointer_size,
|
| DONT_TRACK_ALLOCATION_SITE);
|
| } else {
|
| NoObservableSideEffectsScope no_effects(this);
|
| @@ -4307,7 +4272,6 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| ASSERT(current_block()->HasPredecessor());
|
| ZoneList<Expression*>* subexprs = expr->values();
|
| int length = subexprs->length();
|
| - HValue* context = environment()->context();
|
| HInstruction* literal;
|
|
|
| Handle<AllocationSite> site;
|
| @@ -4341,10 +4305,10 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| ASSERT(!raw_boilerplate.is_null());
|
| ASSERT(site->IsLiteralSite());
|
|
|
| - Handle<JSObject> original_boilerplate_object =
|
| + Handle<JSObject> boilerplate_object =
|
| Handle<JSObject>::cast(raw_boilerplate);
|
| ElementsKind boilerplate_elements_kind =
|
| - Handle<JSObject>::cast(original_boilerplate_object)->GetElementsKind();
|
| + Handle<JSObject>::cast(boilerplate_object)->GetElementsKind();
|
|
|
| // TODO(mvstanton): This heuristic is only a temporary solution. In the
|
| // end, we want to quit creating allocation site info after a certain number
|
| @@ -4353,25 +4317,12 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| boilerplate_elements_kind);
|
|
|
| // Check whether to use fast or slow deep-copying for boilerplate.
|
| - int data_size = 0;
|
| - int pointer_size = 0;
|
| int max_properties = kMaxFastLiteralProperties;
|
| - if (IsFastLiteral(original_boilerplate_object,
|
| + if (IsFastLiteral(boilerplate_object,
|
| kMaxFastLiteralDepth,
|
| - &max_properties,
|
| - &data_size,
|
| - &pointer_size)) {
|
| - if (mode == TRACK_ALLOCATION_SITE) {
|
| - pointer_size += AllocationMemento::kSize;
|
| - }
|
| -
|
| - Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object);
|
| - literal = BuildFastLiteral(context,
|
| - boilerplate_object,
|
| - original_boilerplate_object,
|
| + &max_properties)) {
|
| + literal = BuildFastLiteral(boilerplate_object,
|
| site,
|
| - data_size,
|
| - pointer_size,
|
| mode);
|
| } else {
|
| NoObservableSideEffectsScope no_effects(this);
|
| @@ -4391,8 +4342,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| 3);
|
|
|
| // De-opt if elements kind changed from boilerplate_elements_kind.
|
| - Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
|
| - isolate());
|
| + Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate());
|
| literal = Add<HCheckMaps>(literal, map, top_info());
|
| }
|
|
|
| @@ -5411,8 +5361,6 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
|
| HThrow* instr = Add<HThrow>(value);
|
| instr->set_position(expr->position());
|
| Add<HSimulate>(expr->id());
|
| - current_block()->FinishExit(new(zone()) HAbnormalExit);
|
| - set_current_block(NULL);
|
| }
|
|
|
|
|
| @@ -7115,7 +7063,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
|
|
| CHECK_ALIVE(VisitForValue(expr->expression()));
|
| HValue* function = Pop();
|
| - Add<HCheckFunction>(function, expr->target());
|
| + Add<HCheckValue>(function, expr->target());
|
|
|
| // Replace the global object with the global receiver.
|
| HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object);
|
| @@ -7167,7 +7115,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| HGlobalReceiver* receiver = New<HGlobalReceiver>(global);
|
| PushAndAdd(receiver);
|
| CHECK_ALIVE(VisitExpressions(expr->arguments()));
|
| - Add<HCheckFunction>(function, expr->target());
|
| + Add<HCheckValue>(function, expr->target());
|
|
|
| if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
|
| if (FLAG_trace_inlining) {
|
| @@ -7230,7 +7178,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
|
| HValue* function = Top();
|
| CHECK_ALIVE(VisitExpressions(expr->arguments()));
|
| Handle<JSFunction> constructor = expr->target();
|
| - HValue* check = Add<HCheckFunction>(function, constructor);
|
| + HValue* check = Add<HCheckValue>(function, constructor);
|
|
|
| // Force completion of inobject slack tracking before generating
|
| // allocation code to finalize instance size.
|
| @@ -7322,7 +7270,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
|
| HBinaryCall* call;
|
| if (expr->target().is_identical_to(array_function)) {
|
| Handle<Cell> cell = expr->allocation_info_cell();
|
| - Add<HCheckFunction>(constructor, array_function);
|
| + Add<HCheckValue>(constructor, array_function);
|
| call = new(zone()) HCallNewArray(context, constructor, argument_count,
|
| cell, expr->elements_kind());
|
| } else {
|
| @@ -8154,7 +8102,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
| result->set_position(expr->position());
|
| return ast_context()->ReturnInstruction(result, expr->id());
|
| } else {
|
| - Add<HCheckFunction>(right, target);
|
| + Add<HCheckValue>(right, target);
|
| HInstanceOfKnownGlobal* result =
|
| new(zone()) HInstanceOfKnownGlobal(context, left, target);
|
| result->set_position(expr->position());
|
| @@ -8280,160 +8228,84 @@ HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
|
|
|
|
|
| HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
|
| - HValue* context,
|
| Handle<JSObject> boilerplate_object,
|
| - Handle<JSObject> original_boilerplate_object,
|
| - Handle<Object> allocation_site,
|
| - int data_size,
|
| - int pointer_size,
|
| + Handle<Object> allocation_site_object,
|
| AllocationSiteMode mode) {
|
| NoObservableSideEffectsScope no_effects(this);
|
|
|
| - HInstruction* target = NULL;
|
| - HInstruction* data_target = NULL;
|
| -
|
| - if (isolate()->heap()->GetPretenureMode() == TENURED) {
|
| - if (data_size != 0) {
|
| - HValue* size_in_bytes = Add<HConstant>(data_size);
|
| - data_target = Add<HAllocate>(size_in_bytes, HType::JSObject(), TENURED,
|
| - FIXED_DOUBLE_ARRAY_TYPE);
|
| - Handle<Map> free_space_map = isolate()->factory()->free_space_map();
|
| - AddStoreMapConstant(data_target, free_space_map);
|
| - HObjectAccess access =
|
| - HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
|
| - Add<HStoreNamedField>(data_target, access, size_in_bytes);
|
| - }
|
| - if (pointer_size != 0) {
|
| - HValue* size_in_bytes = Add<HConstant>(pointer_size);
|
| - target = Add<HAllocate>(size_in_bytes, HType::JSObject(), TENURED,
|
| - JS_OBJECT_TYPE);
|
| - }
|
| - } else {
|
| - InstanceType instance_type = boilerplate_object->map()->instance_type();
|
| - HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size);
|
| - target = Add<HAllocate>(size_in_bytes, HType::JSObject(), NOT_TENURED,
|
| - instance_type);
|
| - }
|
| -
|
| - int offset = 0;
|
| - int data_offset = 0;
|
| - BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object,
|
| - allocation_site, target, &offset, data_target,
|
| - &data_offset, mode);
|
| - return target;
|
| -}
|
| -
|
| + Handle<FixedArrayBase> elements(boilerplate_object->elements());
|
| + int object_size = boilerplate_object->map()->instance_size();
|
| + int object_offset = object_size;
|
|
|
| -void HOptimizedGraphBuilder::BuildEmitDeepCopy(
|
| - Handle<JSObject> boilerplate_object,
|
| - Handle<JSObject> original_boilerplate_object,
|
| - Handle<Object> allocation_site_object,
|
| - HInstruction* target,
|
| - int* offset,
|
| - HInstruction* data_target,
|
| - int* data_offset,
|
| - AllocationSiteMode mode) {
|
| bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
|
| - boilerplate_object->map()->CanTrackAllocationSite();
|
| + AllocationSite::CanTrack(boilerplate_object->map()->instance_type());
|
|
|
| // If using allocation sites, then the payload on the site should already
|
| // be filled in as a valid (boilerplate) array.
|
| ASSERT(!create_allocation_site_info ||
|
| AllocationSite::cast(*allocation_site_object)->IsLiteralSite());
|
|
|
| - HInstruction* allocation_site = NULL;
|
| -
|
| if (create_allocation_site_info) {
|
| - allocation_site = Add<HConstant>(allocation_site_object);
|
| + object_size += AllocationMemento::kSize;
|
| }
|
|
|
| - // Only elements backing stores for non-COW arrays need to be copied.
|
| - Handle<FixedArrayBase> elements(boilerplate_object->elements());
|
| - Handle<FixedArrayBase> original_elements(
|
| - original_boilerplate_object->elements());
|
| - ElementsKind kind = boilerplate_object->map()->elements_kind();
|
| + HValue* object_size_constant = Add<HConstant>(object_size);
|
| + HInstruction* object = Add<HAllocate>(object_size_constant, HType::JSObject(),
|
| + isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE);
|
| +
|
| +
|
| + BuildEmitObjectHeader(boilerplate_object, object);
|
| +
|
| + if (create_allocation_site_info) {
|
| + HInstruction* allocation_site = Add<HConstant>(allocation_site_object);
|
| + BuildCreateAllocationMemento(object, object_offset, allocation_site);
|
| + }
|
|
|
| - int object_offset = *offset;
|
| - int object_size = boilerplate_object->map()->instance_size();
|
| int elements_size = (elements->length() > 0 &&
|
| elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
|
| elements->Size() : 0;
|
| - int elements_offset = 0;
|
|
|
| - if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
|
| - elements_offset = *data_offset;
|
| - *data_offset += elements_size;
|
| - } else {
|
| - // Place elements right after this object.
|
| - elements_offset = *offset + object_size;
|
| - *offset += elements_size;
|
| + HInstruction* object_elements = NULL;
|
| + if (elements_size > 0) {
|
| + HValue* object_elements_size = Add<HConstant>(elements_size);
|
| + if (boilerplate_object->HasFastDoubleElements()) {
|
| + object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(),
|
| + isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE);
|
| + } else {
|
| + object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(),
|
| + isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE);
|
| + }
|
| }
|
| - // Increase the offset so that subsequent objects end up right after this
|
| - // object (and it's elements if they are allocated in the same space).
|
| - *offset += object_size;
|
| + BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements);
|
| +
|
|
|
| // Copy object elements if non-COW.
|
| - HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target,
|
| - data_target, object_offset, elements_offset, elements_size);
|
| if (object_elements != NULL) {
|
| - BuildEmitElements(elements, original_elements, kind, object_elements,
|
| - target, offset, data_target, data_offset);
|
| + BuildEmitElements(boilerplate_object, elements, object_elements);
|
| }
|
|
|
| // Copy in-object properties.
|
| if (boilerplate_object->map()->NumberOfFields() != 0) {
|
| - HValue* object_properties =
|
| - Add<HInnerAllocatedObject>(target, object_offset);
|
| - BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object,
|
| - object_properties, target, offset, data_target, data_offset);
|
| - }
|
| -
|
| - // Create allocation site info.
|
| - if (mode == TRACK_ALLOCATION_SITE &&
|
| - boilerplate_object->map()->CanTrackAllocationSite()) {
|
| - elements_offset += AllocationMemento::kSize;
|
| - *offset += AllocationMemento::kSize;
|
| - BuildCreateAllocationMemento(target, JSArray::kSize, allocation_site);
|
| + BuildEmitInObjectProperties(boilerplate_object, object);
|
| }
|
| + return object;
|
| }
|
|
|
|
|
| -HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
|
| +void HOptimizedGraphBuilder::BuildEmitObjectHeader(
|
| Handle<JSObject> boilerplate_object,
|
| - HInstruction* target,
|
| - HInstruction* data_target,
|
| - int object_offset,
|
| - int elements_offset,
|
| - int elements_size) {
|
| + HInstruction* object) {
|
| ASSERT(boilerplate_object->properties()->length() == 0);
|
| - HValue* result = NULL;
|
|
|
| - HValue* object_header = Add<HInnerAllocatedObject>(target, object_offset);
|
| Handle<Map> boilerplate_object_map(boilerplate_object->map());
|
| - AddStoreMapConstant(object_header, boilerplate_object_map);
|
| -
|
| - HInstruction* elements;
|
| - if (elements_size == 0) {
|
| - Handle<Object> elements_field =
|
| - Handle<Object>(boilerplate_object->elements(), isolate());
|
| - elements = Add<HConstant>(elements_field);
|
| - } else {
|
| - if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
|
| - elements = Add<HInnerAllocatedObject>(data_target, elements_offset);
|
| - } else {
|
| - elements = Add<HInnerAllocatedObject>(target, elements_offset);
|
| - }
|
| - result = elements;
|
| - }
|
| - Add<HStoreNamedField>(object_header, HObjectAccess::ForElementsPointer(),
|
| - elements);
|
| + AddStoreMapConstant(object, boilerplate_object_map);
|
|
|
| Handle<Object> properties_field =
|
| Handle<Object>(boilerplate_object->properties(), isolate());
|
| ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
|
| HInstruction* properties = Add<HConstant>(properties_field);
|
| HObjectAccess access = HObjectAccess::ForPropertiesPointer();
|
| - Add<HStoreNamedField>(object_header, access, properties);
|
| + Add<HStoreNamedField>(object, access, properties);
|
|
|
| if (boilerplate_object->IsJSArray()) {
|
| Handle<JSArray> boilerplate_array =
|
| @@ -8443,22 +8315,30 @@ HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
|
| HInstruction* length = Add<HConstant>(length_field);
|
|
|
| ASSERT(boilerplate_array->length()->IsSmi());
|
| - Add<HStoreNamedField>(object_header, HObjectAccess::ForArrayLength(
|
| + Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(
|
| boilerplate_array->GetElementsKind()), length);
|
| }
|
| +}
|
|
|
| - return result;
|
| +
|
| +void HOptimizedGraphBuilder::BuildInitElementsInObjectHeader(
|
| + Handle<JSObject> boilerplate_object,
|
| + HInstruction* object,
|
| + HInstruction* object_elements) {
|
| + ASSERT(boilerplate_object->properties()->length() == 0);
|
| + if (object_elements == NULL) {
|
| + Handle<Object> elements_field =
|
| + Handle<Object>(boilerplate_object->elements(), isolate());
|
| + object_elements = Add<HConstant>(elements_field);
|
| + }
|
| + Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
|
| + object_elements);
|
| }
|
|
|
|
|
| void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| Handle<JSObject> boilerplate_object,
|
| - Handle<JSObject> original_boilerplate_object,
|
| - HValue* object_properties,
|
| - HInstruction* target,
|
| - int* offset,
|
| - HInstruction* data_target,
|
| - int* data_offset) {
|
| + HInstruction* object) {
|
| Handle<DescriptorArray> descriptors(
|
| boilerplate_object->map()->instance_descriptors());
|
| int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
|
| @@ -8482,31 +8362,20 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
|
|
| if (value->IsJSObject()) {
|
| Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
| - Handle<JSObject> original_value_object = Handle<JSObject>::cast(
|
| - Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index),
|
| - isolate()));
|
| - HInstruction* value_instruction = Add<HInnerAllocatedObject>(target,
|
| - *offset);
|
| -
|
| - Add<HStoreNamedField>(object_properties, access, value_instruction);
|
| - BuildEmitDeepCopy(value_object, original_value_object,
|
| - Handle<Object>::null(), target,
|
| - offset, data_target, data_offset,
|
| - DONT_TRACK_ALLOCATION_SITE);
|
| + HInstruction* result =
|
| + BuildFastLiteral(value_object,
|
| + Handle<Object>::null(), DONT_TRACK_ALLOCATION_SITE);
|
| + Add<HStoreNamedField>(object, access, result);
|
| } else {
|
| Representation representation = details.representation();
|
| HInstruction* value_instruction = Add<HConstant>(value);
|
|
|
| if (representation.IsDouble()) {
|
| // Allocate a HeapNumber box and store the value into it.
|
| - HInstruction* double_box;
|
| - if (data_target != NULL) {
|
| - double_box = Add<HInnerAllocatedObject>(data_target, *data_offset);
|
| - *data_offset += HeapNumber::kSize;
|
| - } else {
|
| - double_box = Add<HInnerAllocatedObject>(target, *offset);
|
| - *offset += HeapNumber::kSize;
|
| - }
|
| + HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize);
|
| + HInstruction* double_box =
|
| + Add<HAllocate>(heap_number_constant, HType::HeapNumber(),
|
| + isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE);
|
| AddStoreMapConstant(double_box,
|
| isolate()->factory()->heap_number_map());
|
| Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
|
| @@ -8514,7 +8383,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| value_instruction = double_box;
|
| }
|
|
|
| - Add<HStoreNamedField>(object_properties, access, value_instruction);
|
| + Add<HStoreNamedField>(object, access, value_instruction);
|
| }
|
| }
|
|
|
| @@ -8525,31 +8394,25 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| ASSERT(boilerplate_object->IsJSObject());
|
| int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
|
| HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
|
| - Add<HStoreNamedField>(object_properties, access, value_instruction);
|
| + Add<HStoreNamedField>(object, access, value_instruction);
|
| }
|
| }
|
|
|
|
|
| void HOptimizedGraphBuilder::BuildEmitElements(
|
| + Handle<JSObject> boilerplate_object,
|
| Handle<FixedArrayBase> elements,
|
| - Handle<FixedArrayBase> original_elements,
|
| - ElementsKind kind,
|
| - HValue* object_elements,
|
| - HInstruction* target,
|
| - int* offset,
|
| - HInstruction* data_target,
|
| - int* data_offset) {
|
| + HValue* object_elements) {
|
| + ElementsKind kind = boilerplate_object->map()->elements_kind();
|
| int elements_length = elements->length();
|
| HValue* object_elements_length = Add<HConstant>(elements_length);
|
| -
|
| BuildInitializeElementsHeader(object_elements, kind, object_elements_length);
|
|
|
| // Copy elements backing store content.
|
| if (elements->IsFixedDoubleArray()) {
|
| BuildEmitFixedDoubleArray(elements, kind, object_elements);
|
| } else if (elements->IsFixedArray()) {
|
| - BuildEmitFixedArray(elements, original_elements, kind, object_elements,
|
| - target, offset, data_target, data_offset);
|
| + BuildEmitFixedArray(elements, kind, object_elements);
|
| } else {
|
| UNREACHABLE();
|
| }
|
| @@ -8577,32 +8440,20 @@ void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray(
|
|
|
| void HOptimizedGraphBuilder::BuildEmitFixedArray(
|
| Handle<FixedArrayBase> elements,
|
| - Handle<FixedArrayBase> original_elements,
|
| ElementsKind kind,
|
| - HValue* object_elements,
|
| - HInstruction* target,
|
| - int* offset,
|
| - HInstruction* data_target,
|
| - int* data_offset) {
|
| + HValue* object_elements) {
|
| HInstruction* boilerplate_elements = Add<HConstant>(elements);
|
| int elements_length = elements->length();
|
| Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
|
| - Handle<FixedArray> original_fast_elements =
|
| - Handle<FixedArray>::cast(original_elements);
|
| for (int i = 0; i < elements_length; i++) {
|
| Handle<Object> value(fast_elements->get(i), isolate());
|
| HValue* key_constant = Add<HConstant>(i);
|
| if (value->IsJSObject()) {
|
| Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
| - Handle<JSObject> original_value_object = Handle<JSObject>::cast(
|
| - Handle<Object>(original_fast_elements->get(i), isolate()));
|
| - HInstruction* value_instruction = Add<HInnerAllocatedObject>(target,
|
| - *offset);
|
| - Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind);
|
| - BuildEmitDeepCopy(value_object, original_value_object,
|
| - Handle<Object>::null(), target,
|
| - offset, data_target, data_offset,
|
| - DONT_TRACK_ALLOCATION_SITE);
|
| + HInstruction* result =
|
| + BuildFastLiteral(value_object,
|
| + Handle<Object>::null(), DONT_TRACK_ALLOCATION_SITE);
|
| + Add<HStoreKeyed>(object_elements, key_constant, result, kind);
|
| } else {
|
| HInstruction* value_instruction =
|
| Add<HLoadKeyed>(boilerplate_elements, key_constant,
|
| @@ -9820,15 +9671,15 @@ void HStatistics::Initialize(CompilationInfo* info) {
|
|
|
| void HStatistics::Print() {
|
| PrintF("Timing results:\n");
|
| - int64_t sum = 0;
|
| - for (int i = 0; i < timing_.length(); ++i) {
|
| - sum += timing_[i];
|
| + TimeDelta sum;
|
| + for (int i = 0; i < times_.length(); ++i) {
|
| + sum += times_[i];
|
| }
|
|
|
| for (int i = 0; i < names_.length(); ++i) {
|
| PrintF("%32s", names_[i]);
|
| - double ms = static_cast<double>(timing_[i]) / 1000;
|
| - double percent = static_cast<double>(timing_[i]) * 100 / sum;
|
| + double ms = times_[i].InMillisecondsF();
|
| + double percent = times_[i].PercentOf(sum);
|
| PrintF(" %8.3f ms / %4.1f %% ", ms, percent);
|
|
|
| unsigned size = sizes_[i];
|
| @@ -9838,29 +9689,29 @@ void HStatistics::Print() {
|
|
|
| PrintF("----------------------------------------"
|
| "---------------------------------------\n");
|
| - int64_t total = create_graph_ + optimize_graph_ + generate_code_;
|
| + TimeDelta total = create_graph_ + optimize_graph_ + generate_code_;
|
| PrintF("%32s %8.3f ms / %4.1f %% \n",
|
| "Create graph",
|
| - static_cast<double>(create_graph_) / 1000,
|
| - static_cast<double>(create_graph_) * 100 / total);
|
| + create_graph_.InMillisecondsF(),
|
| + create_graph_.PercentOf(total));
|
| PrintF("%32s %8.3f ms / %4.1f %% \n",
|
| "Optimize graph",
|
| - static_cast<double>(optimize_graph_) / 1000,
|
| - static_cast<double>(optimize_graph_) * 100 / total);
|
| + optimize_graph_.InMillisecondsF(),
|
| + optimize_graph_.PercentOf(total));
|
| PrintF("%32s %8.3f ms / %4.1f %% \n",
|
| "Generate and install code",
|
| - static_cast<double>(generate_code_) / 1000,
|
| - static_cast<double>(generate_code_) * 100 / total);
|
| + generate_code_.InMillisecondsF(),
|
| + generate_code_.PercentOf(total));
|
| PrintF("----------------------------------------"
|
| "---------------------------------------\n");
|
| PrintF("%32s %8.3f ms (%.1f times slower than full code gen)\n",
|
| "Total",
|
| - static_cast<double>(total) / 1000,
|
| - static_cast<double>(total) / full_code_gen_);
|
| + total.InMillisecondsF(),
|
| + total.TimesOf(full_code_gen_));
|
|
|
| double source_size_in_kb = static_cast<double>(source_size_) / 1024;
|
| double normalized_time = source_size_in_kb > 0
|
| - ? (static_cast<double>(total) / 1000) / source_size_in_kb
|
| + ? total.InMillisecondsF() / source_size_in_kb
|
| : 0;
|
| double normalized_size_in_kb = source_size_in_kb > 0
|
| ? total_size_ / 1024 / source_size_in_kb
|
| @@ -9871,17 +9722,17 @@ void HStatistics::Print() {
|
| }
|
|
|
|
|
| -void HStatistics::SaveTiming(const char* name, int64_t ticks, unsigned size) {
|
| +void HStatistics::SaveTiming(const char* name, TimeDelta time, unsigned size) {
|
| total_size_ += size;
|
| for (int i = 0; i < names_.length(); ++i) {
|
| if (strcmp(names_[i], name) == 0) {
|
| - timing_[i] += ticks;
|
| + times_[i] += time;
|
| sizes_[i] += size;
|
| return;
|
| }
|
| }
|
| names_.Add(name);
|
| - timing_.Add(ticks);
|
| + times_.Add(time);
|
| sizes_.Add(size);
|
| }
|
|
|
|
|