| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 0aa96e899cc34f3eb7c46d0bb90650355012130a..f6ac88660a076d62fe66c04c6e10bd1f929245b4 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -4937,8 +4937,8 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
|
| }
|
|
|
|
|
| -static bool CanInlinePropertyAccess(Handle<HeapType> type) {
|
| - if (type->Is(HeapType::NumberOrString())) return true;
|
| +static bool CanInlinePropertyAccess(Type* type) {
|
| + if (type->Is(Type::NumberOrString())) return true;
|
| if (!type->IsClass()) return false;
|
| Handle<Map> map = type->AsClass();
|
| return map->IsJSObjectMap() &&
|
| @@ -4949,11 +4949,12 @@ static bool CanInlinePropertyAccess(Handle<HeapType> type) {
|
|
|
| static void LookupInPrototypes(Handle<Map> map,
|
| Handle<String> name,
|
| - LookupResult* lookup) {
|
| + LookupResult* lookup,
|
| + Zone* zone) {
|
| while (map->prototype()->IsJSObject()) {
|
| Handle<JSObject> holder(JSObject::cast(map->prototype()));
|
| map = handle(holder->map());
|
| - if (!CanInlinePropertyAccess(IC::MapToType(map))) break;
|
| + if (!CanInlinePropertyAccess(IC::MapToType<Type>(map, zone))) break;
|
| map->LookupDescriptor(*holder, *name, lookup);
|
| if (lookup->IsFound()) return;
|
| }
|
| @@ -4968,7 +4969,8 @@ static void LookupInPrototypes(Handle<Map> map,
|
| static bool LookupAccessorPair(Handle<Map> map,
|
| Handle<String> name,
|
| Handle<AccessorPair>* accessors,
|
| - Handle<JSObject>* holder) {
|
| + Handle<JSObject>* holder,
|
| + Zone* zone) {
|
| Isolate* isolate = map->GetIsolate();
|
| LookupResult lookup(isolate);
|
|
|
| @@ -4986,7 +4988,7 @@ static bool LookupAccessorPair(Handle<Map> map,
|
| if (lookup.IsFound()) return false;
|
|
|
| // Check for a JavaScript accessor somewhere in the proto chain.
|
| - LookupInPrototypes(map, name, &lookup);
|
| + LookupInPrototypes(map, name, &lookup, zone);
|
| if (lookup.IsPropertyCallbacks()) {
|
| Handle<Object> callback(lookup.GetValue(), isolate);
|
| if (!callback->IsAccessorPair()) return false;
|
| @@ -5003,9 +5005,10 @@ static bool LookupAccessorPair(Handle<Map> map,
|
| static bool LookupSetter(Handle<Map> map,
|
| Handle<String> name,
|
| Handle<JSFunction>* setter,
|
| - Handle<JSObject>* holder) {
|
| + Handle<JSObject>* holder,
|
| + Zone* zone) {
|
| Handle<AccessorPair> accessors;
|
| - if (LookupAccessorPair(map, name, &accessors, holder) &&
|
| + if (LookupAccessorPair(map, name, &accessors, holder, zone) &&
|
| accessors->setter()->IsJSFunction()) {
|
| Handle<JSFunction> func(JSFunction::cast(accessors->setter()));
|
| CallOptimization call_optimization(func);
|
| @@ -5166,7 +5169,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
|
| #if DEBUG
|
| Handle<JSFunction> setter;
|
| Handle<JSObject> holder;
|
| - ASSERT(!LookupSetter(map, name, &setter, &holder));
|
| + ASSERT(!LookupSetter(map, name, &setter, &holder, zone()));
|
| #endif
|
| CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
|
| name,
|
| @@ -5449,24 +5452,24 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric(
|
|
|
|
|
| // Sets the lookup result and returns true if the load/store can be inlined.
|
| -static bool ComputeStoreField(Handle<Map> type,
|
| +static bool ComputeStoreField(Type* type,
|
| Handle<String> name,
|
| LookupResult* lookup,
|
| bool lookup_transition = true) {
|
| - ASSERT(!type->is_observed());
|
| - if (!CanInlinePropertyAccess(IC::MapToType(type))) {
|
| + if (!CanInlinePropertyAccess(type) || !type->IsClass()) {
|
| lookup->NotFound();
|
| return false;
|
| }
|
| + Handle<Map> map = type->AsClass();
|
| + ASSERT(!map->is_observed());
|
| // If we directly find a field, the access can be inlined.
|
| - type->LookupDescriptor(NULL, *name, lookup);
|
| + map->LookupDescriptor(NULL, *name, lookup);
|
| if (lookup->IsField()) return true;
|
|
|
| if (!lookup_transition) return false;
|
|
|
| - type->LookupTransition(NULL, *name, lookup);
|
| - return lookup->IsTransitionToField(*type) &&
|
| - (type->unused_property_fields() > 0);
|
| + map->LookupTransition(NULL, *name, lookup);
|
| + return lookup->IsTransitionToField(*map) && map->unused_property_fields() > 0;
|
| }
|
|
|
|
|
| @@ -5477,7 +5480,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic(
|
| Handle<Map> map) {
|
| // Handle a store to a known field.
|
| LookupResult lookup(isolate());
|
| - if (ComputeStoreField(map, name, &lookup)) {
|
| + if (ComputeStoreField(ToType(map), name, &lookup)) {
|
| HCheckMaps* checked_object = AddCheckMap(object, map);
|
| return BuildStoreNamedField(checked_object, name, value, map, &lookup);
|
| }
|
| @@ -5491,17 +5494,17 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatibleForLoad(
|
| PropertyAccessInfo* info) {
|
| if (!CanInlinePropertyAccess(type_)) return false;
|
|
|
| - // Currently only handle HeapType::Number as a polymorphic case.
|
| + // Currently only handle Type::Number as a polymorphic case.
|
| // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
|
| // instruction.
|
| - if (type_->Is(HeapType::Number())) return false;
|
| + if (type_->Is(Type::Number())) return false;
|
|
|
| // Values are only compatible for monomorphic load if they all behave the same
|
| // regarding value wrappers.
|
| - if (type_->Is(HeapType::NumberOrString())) {
|
| - if (!info->type_->Is(HeapType::NumberOrString())) return false;
|
| + if (type_->Is(Type::NumberOrString())) {
|
| + if (!info->type_->Is(Type::NumberOrString())) return false;
|
| } else {
|
| - if (info->type_->Is(HeapType::NumberOrString())) return false;
|
| + if (info->type_->Is(Type::NumberOrString())) return false;
|
| }
|
|
|
| if (!LookupDescriptor()) return false;
|
| @@ -5572,7 +5575,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
|
| JSObject::TryMigrateInstance(holder_);
|
| }
|
| map = Handle<Map>(holder_->map());
|
| - if (!CanInlinePropertyAccess(IC::MapToType(map))) {
|
| + if (!CanInlinePropertyAccess(ToType(map))) {
|
| lookup_.NotFound();
|
| return false;
|
| }
|
| @@ -5595,7 +5598,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadMonomorphic() {
|
|
|
| bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
|
| SmallMapList* types) {
|
| - ASSERT(type_->Is(IC::MapToType(types->first())));
|
| + ASSERT(type_->Is(ToType(types->first())));
|
| if (!CanLoadMonomorphic()) return false;
|
| if (types->length() > kMaxLoadPolymorphism) return false;
|
|
|
| @@ -5614,8 +5617,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
|
| HObjectAccess access = HObjectAccess::ForMap(); // bogus default
|
| if (GetJSObjectFieldAccess(&access)) {
|
| for (int i = 1; i < types->length(); ++i) {
|
| - PropertyAccessInfo test_info(
|
| - builder_, IC::MapToType(types->at(i)), name_);
|
| + PropertyAccessInfo test_info(builder_, ToType(types->at(i)), name_);
|
| HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default
|
| if (!test_info.GetJSObjectFieldAccess(&test_access)) return false;
|
| if (!access.Equals(test_access)) return false;
|
| @@ -5623,13 +5625,13 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
|
| return true;
|
| }
|
|
|
| - // Currently only handle HeapType::Number as a polymorphic case.
|
| + // Currently only handle Type::Number as a polymorphic case.
|
| // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
|
| // instruction.
|
| - if (type_->Is(HeapType::Number())) return false;
|
| + if (type_->Is(Type::Number())) return false;
|
|
|
| for (int i = 1; i < types->length(); ++i) {
|
| - PropertyAccessInfo test_info(builder_, IC::MapToType(types->at(i)), name_);
|
| + PropertyAccessInfo test_info(builder_, ToType(types->at(i)), name_);
|
| if (!test_info.IsCompatibleForLoad(this)) return false;
|
| }
|
|
|
| @@ -5637,8 +5639,8 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
|
| }
|
|
|
|
|
| -static bool NeedsWrappingFor(Handle<HeapType> type, Handle<JSFunction> target) {
|
| - return type->Is(HeapType::NumberOrString()) &&
|
| +static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) {
|
| + return type->Is(Type::NumberOrString()) &&
|
| target->shared()->is_classic_mode() &&
|
| !target->shared()->native();
|
| }
|
| @@ -5706,14 +5708,14 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
|
|
|
| bool handle_smi = false;
|
| for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
|
| - PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name);
|
| - if (info.type()->Is(HeapType::String())) {
|
| + PropertyAccessInfo info(this, ToType(types->at(i)), name);
|
| + if (info.type()->Is(Type::String())) {
|
| if (handled_string) continue;
|
| handled_string = true;
|
| }
|
| if (info.CanLoadMonomorphic()) {
|
| count++;
|
| - if (info.type()->Is(HeapType::Number())) {
|
| + if (info.type()->Is(Type::Number())) {
|
| handle_smi = true;
|
| break;
|
| }
|
| @@ -5725,8 +5727,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
|
| handled_string = false;
|
|
|
| for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
|
| - PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name);
|
| - if (info.type()->Is(HeapType::String())) {
|
| + PropertyAccessInfo info(this, ToType(types->at(i)), name);
|
| + if (info.type()->Is(Type::String())) {
|
| if (handled_string) continue;
|
| handled_string = true;
|
| }
|
| @@ -5753,11 +5755,11 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
|
| HUnaryControlInstruction* compare;
|
|
|
| HValue* dependency;
|
| - if (info.type()->Is(HeapType::Number())) {
|
| + if (info.type()->Is(Type::Number())) {
|
| Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
|
| compare = New<HCompareMap>(object, heap_number_map, if_true, if_false);
|
| dependency = smi_check;
|
| - } else if (info.type()->Is(HeapType::String())) {
|
| + } else if (info.type()->Is(Type::String())) {
|
| compare = New<HIsStringAndBranch>(object, if_true, if_false);
|
| dependency = compare;
|
| } else {
|
| @@ -5766,7 +5768,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
|
| }
|
| FinishCurrentBlock(compare);
|
|
|
| - if (info.type()->Is(HeapType::Number())) {
|
| + if (info.type()->Is(Type::Number())) {
|
| Goto(if_true, number_block);
|
| if_true = number_block;
|
| number_block->SetJoinId(ast_id);
|
| @@ -5836,7 +5838,7 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
|
| for (count = 0; count < types->length(); ++count) {
|
| Handle<Map> map = types->at(count);
|
| // Pass false to ignore transitions.
|
| - if (!ComputeStoreField(map, name, &lookup, false)) break;
|
| + if (!ComputeStoreField(ToType(map), name, &lookup, false)) break;
|
| ASSERT(!map->is_observed());
|
|
|
| HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
|
| @@ -5896,7 +5898,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
|
| for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
|
| Handle<Map> map = types->at(i);
|
| LookupResult lookup(isolate());
|
| - if (ComputeStoreField(map, name, &lookup)) {
|
| + if (ComputeStoreField(ToType(map), name, &lookup)) {
|
| if (count == 0) {
|
| BuildCheckHeapObject(object);
|
| join = graph()->CreateBasicBlock();
|
| @@ -5962,7 +5964,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
|
|
|
| static bool ComputeReceiverTypes(Expression* expr,
|
| HValue* receiver,
|
| - SmallMapList** t) {
|
| + SmallMapList** t,
|
| + Zone* zone) {
|
| SmallMapList* types = expr->GetReceiverTypes();
|
| *t = types;
|
| bool monomorphic = expr->IsMonomorphic();
|
| @@ -5971,7 +5974,8 @@ static bool ComputeReceiverTypes(Expression* expr,
|
| types->FilterForPossibleTransitions(root_map);
|
| monomorphic = types->length() == 1;
|
| }
|
| - return monomorphic && CanInlinePropertyAccess(IC::MapToType(types->first()));
|
| + return monomorphic && CanInlinePropertyAccess(
|
| + IC::MapToType<Type>(types->first(), zone));
|
| }
|
|
|
|
|
| @@ -6011,16 +6015,16 @@ void HOptimizedGraphBuilder::BuildStore(Expression* expr,
|
| HInstruction* instr = NULL;
|
|
|
| SmallMapList* types;
|
| - bool monomorphic = ComputeReceiverTypes(expr, object, &types);
|
| + bool monomorphic = ComputeReceiverTypes(expr, object, &types, zone());
|
|
|
| if (monomorphic) {
|
| Handle<Map> map = types->first();
|
| Handle<JSFunction> setter;
|
| Handle<JSObject> holder;
|
| - if (LookupSetter(map, name, &setter, &holder)) {
|
| + if (LookupSetter(map, name, &setter, &holder, zone())) {
|
| AddCheckMap(object, map);
|
| AddCheckPrototypeMaps(holder, map);
|
| - bool needs_wrapping = NeedsWrappingFor(IC::MapToType(map), setter);
|
| + bool needs_wrapping = NeedsWrappingFor(ToType(map), setter);
|
| bool try_inline = FLAG_inline_accessors && !needs_wrapping;
|
| if (try_inline && TryInlineSetter(setter, ast_id, return_id, value)) {
|
| return;
|
| @@ -6700,7 +6704,7 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
|
| HInstruction* instr = NULL;
|
|
|
| SmallMapList* types;
|
| - bool monomorphic = ComputeReceiverTypes(expr, obj, &types);
|
| + bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
|
|
|
| bool force_generic = false;
|
| if (is_store && (monomorphic || (types != NULL && !types->is_empty()))) {
|
| @@ -6882,19 +6886,19 @@ void HOptimizedGraphBuilder::BuildLoad(Property* expr,
|
| HValue* object = Pop();
|
|
|
| SmallMapList* types;
|
| - ComputeReceiverTypes(expr, object, &types);
|
| + ComputeReceiverTypes(expr, object, &types, zone());
|
| ASSERT(types != NULL);
|
|
|
| if (types->length() > 0) {
|
| - PropertyAccessInfo info(this, IC::MapToType(types->first()), name);
|
| + PropertyAccessInfo info(this, ToType(types->first()), name);
|
| if (!info.CanLoadAsMonomorphic(types)) {
|
| return HandlePolymorphicLoadNamedField(
|
| ast_id, expr->LoadId(), object, types, name);
|
| }
|
|
|
| HValue* checked_object;
|
| - // HeapType::Number() is only supported by polymorphic load/call handling.
|
| - ASSERT(!info.type()->Is(HeapType::Number()));
|
| + // Type::Number() is only supported by polymorphic load/call handling.
|
| + ASSERT(!info.type()->Is(Type::Number()));
|
| BuildCheckHeapObject(object);
|
| if (AreStringTypes(types)) {
|
| checked_object =
|
| @@ -7094,16 +7098,16 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
| for (int i = 0;
|
| i < types->length() && ordered_functions < kMaxCallPolymorphism;
|
| ++i) {
|
| - PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name);
|
| + PropertyAccessInfo info(this, ToType(types->at(i)), name);
|
| if (info.CanLoadMonomorphic() &&
|
| info.lookup()->IsConstant() &&
|
| info.constant()->IsJSFunction()) {
|
| - if (info.type()->Is(HeapType::String())) {
|
| + if (info.type()->Is(Type::String())) {
|
| if (handled_string) continue;
|
| handled_string = true;
|
| }
|
| Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
|
| - if (info.type()->Is(HeapType::Number())) {
|
| + if (info.type()->Is(Type::Number())) {
|
| handle_smi = true;
|
| }
|
| expr->set_target(target);
|
| @@ -7124,8 +7128,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
|
|
| for (int fn = 0; fn < ordered_functions; ++fn) {
|
| int i = order[fn].index();
|
| - PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name);
|
| - if (info.type()->Is(HeapType::String())) {
|
| + PropertyAccessInfo info(this, ToType(types->at(i)), name);
|
| + if (info.type()->Is(Type::String())) {
|
| if (handled_string) continue;
|
| handled_string = true;
|
| }
|
| @@ -7155,17 +7159,17 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
| HUnaryControlInstruction* compare;
|
|
|
| Handle<Map> map = info.map();
|
| - if (info.type()->Is(HeapType::Number())) {
|
| + if (info.type()->Is(Type::Number())) {
|
| Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
|
| compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false);
|
| - } else if (info.type()->Is(HeapType::String())) {
|
| + } else if (info.type()->Is(Type::String())) {
|
| compare = New<HIsStringAndBranch>(receiver, if_true, if_false);
|
| } else {
|
| compare = New<HCompareMap>(receiver, map, if_true, if_false);
|
| }
|
| FinishCurrentBlock(compare);
|
|
|
| - if (info.type()->Is(HeapType::Number())) {
|
| + if (info.type()->Is(Type::Number())) {
|
| Goto(if_true, number_block);
|
| if_true = number_block;
|
| number_block->SetJoinId(expr->id());
|
| @@ -8113,11 +8117,11 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| HValue* receiver = Top();
|
|
|
| SmallMapList* types;
|
| - ComputeReceiverTypes(expr, receiver, &types);
|
| + ComputeReceiverTypes(expr, receiver, &types, zone());
|
|
|
| if (prop->key()->IsPropertyName() && types->length() > 0) {
|
| Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
|
| - PropertyAccessInfo info(this, IC::MapToType(types->first()), name);
|
| + PropertyAccessInfo info(this, ToType(types->first()), name);
|
| if (!info.CanLoadAsMonomorphic(types)) {
|
| HandlePolymorphicCallNamed(expr, receiver, types, name);
|
| return;
|
| @@ -8159,7 +8163,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| if (TryInlineApiMethodCall(expr, receiver, map)) return;
|
|
|
| // Wrap the receiver if necessary.
|
| - if (NeedsWrappingFor(IC::MapToType(types->first()), known_function)) {
|
| + if (NeedsWrappingFor(ToType(types->first()), known_function)) {
|
| // Since HWrapReceiver currently cannot actually wrap numbers and
|
| // strings, use the regular CallFunctionStub for method calls to wrap
|
| // the receiver.
|
|
|