| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 5bb0764742ce79c94d675b96e5ebe1efea53331d..13aea0144eb6e2f94ea1d2c563d9b967d0707af2 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -1092,10 +1092,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
|
| HAdd::New(zone, context, key, graph_->GetConstant1()));
|
| new_length->ClearFlag(HValue::kCanOverflow);
|
|
|
| - Representation representation = IsFastElementsKind(kind)
|
| - ? Representation::Smi() : Representation::Tagged();
|
| - AddStore(object, HObjectAccess::ForArrayLength(), new_length,
|
| - representation);
|
| + AddStore(object, HObjectAccess::ForArrayLength(kind), new_length);
|
| }
|
|
|
| length_checker.Else();
|
| @@ -1163,10 +1160,8 @@ void HGraphBuilder::BuildTransitionElementsKind(HValue* object,
|
| HInstruction* elements_length = AddLoadFixedArrayLength(elements);
|
|
|
| HInstruction* array_length = is_jsarray
|
| - ? AddLoad(object, HObjectAccess::ForArrayLength(),
|
| - NULL, Representation::Smi())
|
| + ? AddLoad(object, HObjectAccess::ForArrayLength(from_kind), NULL)
|
| : elements_length;
|
| - array_length->set_type(HType::Smi());
|
|
|
| BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
|
| array_length, elements_length);
|
| @@ -1214,8 +1209,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
|
| }
|
| HInstruction* length = NULL;
|
| if (is_js_array) {
|
| - length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck,
|
| - Representation::Smi());
|
| + length = AddLoad(object, HObjectAccess::ForArrayLength(elements_kind),
|
| + mapcheck);
|
| } else {
|
| length = AddLoadFixedArrayLength(elements);
|
| }
|
| @@ -1331,10 +1326,7 @@ void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
|
| : factory->fixed_array_map();
|
|
|
| AddStoreMapConstant(elements, map);
|
| - Representation representation = IsFastElementsKind(kind)
|
| - ? Representation::Smi() : Representation::Tagged();
|
| - AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity,
|
| - representation);
|
| + AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity);
|
| }
|
|
|
|
|
| @@ -1351,6 +1343,7 @@ HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
|
| HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
|
| HValue* array_map,
|
| AllocationSiteMode mode,
|
| + ElementsKind elements_kind,
|
| HValue* allocation_site_payload,
|
| HValue* length_field) {
|
|
|
| @@ -1361,7 +1354,7 @@ HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
|
|
|
| HObjectAccess access = HObjectAccess::ForPropertiesPointer();
|
| AddStore(array, access, empty_fixed_array);
|
| - AddStore(array, HObjectAccess::ForArrayLength(), length_field);
|
| + AddStore(array, HObjectAccess::ForArrayLength(elements_kind), length_field);
|
|
|
| if (mode == TRACK_ALLOCATION_SITE) {
|
| BuildCreateAllocationMemento(array,
|
| @@ -1468,10 +1461,7 @@ HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
|
|
|
|
|
| HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
|
| - HLoadNamedField* instr = AddLoad(object, HObjectAccess::ForFixedArrayLength(),
|
| - NULL, Representation::Smi());
|
| - instr->set_type(HType::Smi());
|
| - return instr;
|
| + return AddLoad(object, HObjectAccess::ForFixedArrayLength());
|
| }
|
|
|
|
|
| @@ -1842,11 +1832,8 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
|
| // No need for a context lookup if the kind_ matches the initial
|
| // map, because we can just load the map in that case.
|
| HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
|
| - HInstruction* load =
|
| - builder()->BuildLoadNamedField(constructor_function_,
|
| - access,
|
| - Representation::Tagged());
|
| - return builder()->AddInstruction(load);
|
| + return builder()->AddInstruction(
|
| + builder()->BuildLoadNamedField(constructor_function_, access));
|
| }
|
|
|
| HInstruction* native_context = builder()->BuildGetNativeContext(context);
|
| @@ -1867,9 +1854,7 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
|
| // Find the map near the constructor function
|
| HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
|
| return builder()->AddInstruction(
|
| - builder()->BuildLoadNamedField(constructor_function_,
|
| - access,
|
| - Representation::Tagged()));
|
| + builder()->BuildLoadNamedField(constructor_function_, access));
|
| }
|
|
|
|
|
| @@ -1957,6 +1942,7 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
|
| elements_location_ = builder()->BuildJSArrayHeader(new_object,
|
| map,
|
| mode_,
|
| + kind_,
|
| allocation_site_payload_,
|
| length_field);
|
|
|
| @@ -1974,17 +1960,15 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
|
|
|
| HStoreNamedField* HGraphBuilder::AddStore(HValue *object,
|
| HObjectAccess access,
|
| - HValue *val,
|
| - Representation representation) {
|
| - return Add<HStoreNamedField>(object, access, val, representation);
|
| + HValue *val) {
|
| + return Add<HStoreNamedField>(object, access, val);
|
| }
|
|
|
|
|
| HLoadNamedField* HGraphBuilder::AddLoad(HValue *object,
|
| HObjectAccess access,
|
| - HValue *typecheck,
|
| - Representation representation) {
|
| - return Add<HLoadNamedField>(object, access, typecheck, representation);
|
| + HValue *typecheck) {
|
| + return Add<HLoadNamedField>(object, access, typecheck);
|
| }
|
|
|
|
|
| @@ -4526,20 +4510,6 @@ static bool ComputeLoadStoreField(Handle<Map> type,
|
| }
|
|
|
|
|
| -static Representation ComputeLoadStoreRepresentation(Handle<Map> type,
|
| - LookupResult* lookup) {
|
| - if (lookup->IsField()) {
|
| - return lookup->representation();
|
| - } else {
|
| - Map* transition = lookup->GetTransitionMapFromMap(*type);
|
| - int descriptor = transition->LastAdded();
|
| - PropertyDetails details =
|
| - transition->instance_descriptors()->GetDetails(descriptor);
|
| - return details.representation();
|
| - }
|
| -}
|
| -
|
| -
|
| void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
|
| BuildCheckHeapObject(object);
|
| AddInstruction(HCheckMaps::New(object, map, zone(), top_info()));
|
| @@ -4591,33 +4561,33 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
|
| }
|
|
|
| HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
|
| - Representation representation = ComputeLoadStoreRepresentation(map, lookup);
|
| bool transition_to_field = lookup->IsTransitionToField(*map);
|
|
|
| HStoreNamedField *instr;
|
| - if (FLAG_track_double_fields && representation.IsDouble()) {
|
| + if (FLAG_track_double_fields && field_access.representation().IsDouble()) {
|
| + HObjectAccess heap_number_access =
|
| + field_access.WithRepresentation(Representation::Tagged());
|
| if (transition_to_field) {
|
| // The store requires a mutable HeapNumber to be allocated.
|
| NoObservableSideEffectsScope no_side_effects(this);
|
| HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
|
| - HInstruction* double_box = Add<HAllocate>(
|
| + HInstruction* heap_number = Add<HAllocate>(
|
| environment()->LookupContext(), heap_number_size,
|
| HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE);
|
| - AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map());
|
| - AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
|
| - value, Representation::Double());
|
| - instr = new(zone()) HStoreNamedField(object, field_access, double_box);
|
| + AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
|
| + AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value);
|
| + instr = new(zone()) HStoreNamedField(
|
| + object, heap_number_access, heap_number);
|
| } else {
|
| // Already holds a HeapNumber; load the box and write its value field.
|
| - HInstruction* double_box = AddLoad(object, field_access);
|
| - double_box->set_type(HType::HeapNumber());
|
| - instr = new(zone()) HStoreNamedField(double_box,
|
| - HObjectAccess::ForHeapNumberValue(), value, Representation::Double());
|
| + HInstruction* heap_number = AddLoad(object, heap_number_access);
|
| + heap_number->set_type(HType::HeapNumber());
|
| + instr = new(zone()) HStoreNamedField(heap_number,
|
| + HObjectAccess::ForHeapNumberValue(), value);
|
| }
|
| } else {
|
| - // This is a non-double store.
|
| - instr = new(zone()) HStoreNamedField(
|
| - object, field_access, value, representation);
|
| + // This is a normal store.
|
| + instr = new(zone()) HStoreNamedField(object, field_access, value);
|
| }
|
|
|
| if (transition_to_field) {
|
| @@ -4684,20 +4654,18 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
|
|
|
| LookupResult lookup(isolate());
|
| int count;
|
| - Representation representation = Representation::None();
|
| HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
|
| for (count = 0; count < types->length(); ++count) {
|
| Handle<Map> map = types->at(count);
|
| if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
|
|
|
| HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
|
| - Representation new_representation =
|
| - ComputeLoadStoreRepresentation(map, &lookup);
|
|
|
| if (count == 0) {
|
| // First time through the loop; set access and representation.
|
| access = new_access;
|
| - } else if (!representation.IsCompatibleForLoad(new_representation)) {
|
| + } else if (!access.representation().IsCompatibleForLoad(
|
| + new_access.representation())) {
|
| // Representations did not match.
|
| break;
|
| } else if (access.offset() != new_access.offset()) {
|
| @@ -4707,14 +4675,15 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
|
| // In-objectness did not match.
|
| break;
|
| }
|
| - representation = representation.generalize(new_representation);
|
| + access = access.WithRepresentation(
|
| + access.representation().generalize(new_access.representation()));
|
| }
|
|
|
| if (count == types->length()) {
|
| // Everything matched; can use monomorphic load.
|
| BuildCheckHeapObject(object);
|
| AddInstruction(HCheckMaps::New(object, types, zone()));
|
| - return BuildLoadNamedField(object, access, representation);
|
| + return BuildLoadNamedField(object, access);
|
| }
|
|
|
| if (count != 0) return NULL;
|
| @@ -4736,14 +4705,14 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
|
|
|
| BuildCheckHeapObject(object);
|
| AddInstruction(HCheckMaps::New(object, types, zone()));
|
| +
|
| Handle<JSObject> holder(lookup.holder());
|
| Handle<Map> holder_map(holder->map());
|
| AddInstruction(new(zone()) HCheckPrototypeMaps(
|
| Handle<JSObject>::cast(prototype), holder, zone(), top_info()));
|
| HValue* holder_value = AddInstruction(new(zone()) HConstant(holder));
|
| return BuildLoadNamedField(holder_value,
|
| - HObjectAccess::ForField(holder_map, &lookup, name),
|
| - ComputeLoadStoreRepresentation(map, &lookup));
|
| + HObjectAccess::ForField(holder_map, &lookup, name));
|
| }
|
|
|
|
|
| @@ -4792,8 +4761,7 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
|
| ASSERT(!map->is_observed());
|
|
|
| HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
|
| - Representation new_representation =
|
| - ComputeLoadStoreRepresentation(map, &lookup);
|
| + Representation new_representation = new_access.representation();
|
|
|
| if (count == 0) {
|
| // First time through the loop; set access and representation.
|
| @@ -5386,24 +5354,18 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
|
| }
|
|
|
|
|
| -HLoadNamedField* HGraphBuilder::BuildLoadNamedField(
|
| - HValue* object,
|
| - HObjectAccess access,
|
| - Representation representation) {
|
| - bool load_double = false;
|
| - if (representation.IsDouble()) {
|
| - representation = Representation::Tagged();
|
| - load_double = FLAG_track_double_fields;
|
| - }
|
| - HLoadNamedField* field =
|
| - new(zone()) HLoadNamedField(object, access, NULL, representation);
|
| - if (load_double) {
|
| - AddInstruction(field);
|
| - field->set_type(HType::HeapNumber());
|
| - return new(zone()) HLoadNamedField(field,
|
| - HObjectAccess::ForHeapNumberValue(), NULL, Representation::Double());
|
| +HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
|
| + HObjectAccess access) {
|
| + if (FLAG_track_double_fields && access.representation().IsDouble()) {
|
| + // load the heap number
|
| + HLoadNamedField* heap_number =
|
| + AddLoad(object, access.WithRepresentation(Representation::Tagged()));
|
| + heap_number->set_type(HType::HeapNumber());
|
| + // load the double value from it
|
| + return new(zone()) HLoadNamedField(heap_number,
|
| + HObjectAccess::ForHeapNumberValue(), NULL);
|
| }
|
| - return field;
|
| + return new(zone()) HLoadNamedField(object, access, NULL);
|
| }
|
|
|
|
|
| @@ -5443,7 +5405,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
|
| if (map->instance_type() == JS_ARRAY_TYPE) {
|
| AddCheckMapsWithTransitions(object, map);
|
| return new(zone()) HLoadNamedField(object,
|
| - HObjectAccess::ForArrayLength());
|
| + HObjectAccess::ForArrayLength(map->elements_kind()));
|
| }
|
| }
|
|
|
| @@ -5452,8 +5414,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
|
| if (lookup.IsField()) {
|
| AddCheckMap(object, map);
|
| return BuildLoadNamedField(object,
|
| - HObjectAccess::ForField(map, &lookup, name),
|
| - ComputeLoadStoreRepresentation(map, &lookup));
|
| + HObjectAccess::ForField(map, &lookup, name));
|
| }
|
|
|
| // Handle a load of a constant known function.
|
| @@ -5473,8 +5434,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
|
| Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
|
| HValue* holder_value = Add<HConstant>(holder);
|
| return BuildLoadNamedField(holder_value,
|
| - HObjectAccess::ForField(holder_map, &lookup, name),
|
| - ComputeLoadStoreRepresentation(map, &lookup));
|
| + HObjectAccess::ForField(holder_map, &lookup, name));
|
| }
|
|
|
| // Handle a load of a constant function somewhere in the prototype chain.
|
| @@ -5696,9 +5656,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
|
| zone(), top_info(), mapcompare));
|
| }
|
| if (map->IsJSArray()) {
|
| - HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(),
|
| - mapcompare, Representation::Smi());
|
| - length->set_type(HType::Smi());
|
| + HInstruction* length = AddLoad(
|
| + object, HObjectAccess::ForArrayLength(elements_kind), mapcompare);
|
| checked_key = Add<HBoundsCheck>(key, length);
|
| } else {
|
| HInstruction* length = AddLoadFixedArrayLength(elements);
|
| @@ -8490,11 +8449,8 @@ HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
|
| HInstruction* length = Add<HConstant>(length_field);
|
|
|
| ASSERT(boilerplate_array->length()->IsSmi());
|
| - Representation representation =
|
| - IsFastElementsKind(boilerplate_array->GetElementsKind())
|
| - ? Representation::Smi() : Representation::Tagged();
|
| - AddStore(object_header, HObjectAccess::ForArrayLength(),
|
| - length, representation);
|
| + AddStore(object_header, HObjectAccess::ForArrayLength(
|
| + boilerplate_array->GetElementsKind()), length);
|
| }
|
|
|
| return result;
|
| @@ -8560,7 +8516,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| AddStoreMapConstant(double_box,
|
| isolate()->factory()->heap_number_map());
|
| AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
|
| - value_instruction, Representation::Double());
|
| + value_instruction);
|
| value_instruction = double_box;
|
| }
|
|
|
|
|