Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: src/hydrogen.cc

Issue 152863002: Use Type* in crankshaft rather than HeapType. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/ic.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4919 matching lines...) Expand 10 before | Expand all | Expand 10 after
4930 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4930 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4931 Handle<FixedArray> literals(closure->literals()); 4931 Handle<FixedArray> literals(closure->literals());
4932 HRegExpLiteral* instr = New<HRegExpLiteral>(literals, 4932 HRegExpLiteral* instr = New<HRegExpLiteral>(literals,
4933 expr->pattern(), 4933 expr->pattern(),
4934 expr->flags(), 4934 expr->flags(),
4935 expr->literal_index()); 4935 expr->literal_index());
4936 return ast_context()->ReturnInstruction(instr, expr->id()); 4936 return ast_context()->ReturnInstruction(instr, expr->id());
4937 } 4937 }
4938 4938
4939 4939
4940 static bool CanInlinePropertyAccess(Handle<HeapType> type) { 4940 static bool CanInlinePropertyAccess(Type* type) {
4941 if (type->Is(HeapType::NumberOrString())) return true; 4941 if (type->Is(Type::NumberOrString())) return true;
4942 if (!type->IsClass()) return false; 4942 if (!type->IsClass()) return false;
4943 Handle<Map> map = type->AsClass(); 4943 Handle<Map> map = type->AsClass();
4944 return map->IsJSObjectMap() && 4944 return map->IsJSObjectMap() &&
4945 !map->is_dictionary_map() && 4945 !map->is_dictionary_map() &&
4946 !map->has_named_interceptor(); 4946 !map->has_named_interceptor();
4947 } 4947 }
4948 4948
4949 4949
4950 static void LookupInPrototypes(Handle<Map> map, 4950 static void LookupInPrototypes(Handle<Map> map,
4951 Handle<String> name, 4951 Handle<String> name,
4952 LookupResult* lookup) { 4952 LookupResult* lookup,
4953 Zone* zone) {
4953 while (map->prototype()->IsJSObject()) { 4954 while (map->prototype()->IsJSObject()) {
4954 Handle<JSObject> holder(JSObject::cast(map->prototype())); 4955 Handle<JSObject> holder(JSObject::cast(map->prototype()));
4955 map = handle(holder->map()); 4956 map = handle(holder->map());
4956 if (!CanInlinePropertyAccess(IC::MapToType(map))) break; 4957 if (!CanInlinePropertyAccess(IC::MapToType<Type>(map, zone))) break;
4957 map->LookupDescriptor(*holder, *name, lookup); 4958 map->LookupDescriptor(*holder, *name, lookup);
4958 if (lookup->IsFound()) return; 4959 if (lookup->IsFound()) return;
4959 } 4960 }
4960 lookup->NotFound(); 4961 lookup->NotFound();
4961 } 4962 }
4962 4963
4963 4964
4964 // Tries to find a JavaScript accessor of the given name in the prototype chain 4965 // Tries to find a JavaScript accessor of the given name in the prototype chain
4965 // starting at the given map. Return true iff there is one, including the 4966 // starting at the given map. Return true iff there is one, including the
4966 // corresponding AccessorPair plus its holder (which could be null when the 4967 // corresponding AccessorPair plus its holder (which could be null when the
4967 // accessor is found directly in the given map). 4968 // accessor is found directly in the given map).
4968 static bool LookupAccessorPair(Handle<Map> map, 4969 static bool LookupAccessorPair(Handle<Map> map,
4969 Handle<String> name, 4970 Handle<String> name,
4970 Handle<AccessorPair>* accessors, 4971 Handle<AccessorPair>* accessors,
4971 Handle<JSObject>* holder) { 4972 Handle<JSObject>* holder,
4973 Zone* zone) {
4972 Isolate* isolate = map->GetIsolate(); 4974 Isolate* isolate = map->GetIsolate();
4973 LookupResult lookup(isolate); 4975 LookupResult lookup(isolate);
4974 4976
4975 // Check for a JavaScript accessor directly in the map. 4977 // Check for a JavaScript accessor directly in the map.
4976 map->LookupDescriptor(NULL, *name, &lookup); 4978 map->LookupDescriptor(NULL, *name, &lookup);
4977 if (lookup.IsPropertyCallbacks()) { 4979 if (lookup.IsPropertyCallbacks()) {
4978 Handle<Object> callback(lookup.GetValueFromMap(*map), isolate); 4980 Handle<Object> callback(lookup.GetValueFromMap(*map), isolate);
4979 if (!callback->IsAccessorPair()) return false; 4981 if (!callback->IsAccessorPair()) return false;
4980 *accessors = Handle<AccessorPair>::cast(callback); 4982 *accessors = Handle<AccessorPair>::cast(callback);
4981 *holder = Handle<JSObject>(); 4983 *holder = Handle<JSObject>();
4982 return true; 4984 return true;
4983 } 4985 }
4984 4986
4985 // Everything else, e.g. a field, can't be an accessor call. 4987 // Everything else, e.g. a field, can't be an accessor call.
4986 if (lookup.IsFound()) return false; 4988 if (lookup.IsFound()) return false;
4987 4989
4988 // Check for a JavaScript accessor somewhere in the proto chain. 4990 // Check for a JavaScript accessor somewhere in the proto chain.
4989 LookupInPrototypes(map, name, &lookup); 4991 LookupInPrototypes(map, name, &lookup, zone);
4990 if (lookup.IsPropertyCallbacks()) { 4992 if (lookup.IsPropertyCallbacks()) {
4991 Handle<Object> callback(lookup.GetValue(), isolate); 4993 Handle<Object> callback(lookup.GetValue(), isolate);
4992 if (!callback->IsAccessorPair()) return false; 4994 if (!callback->IsAccessorPair()) return false;
4993 *accessors = Handle<AccessorPair>::cast(callback); 4995 *accessors = Handle<AccessorPair>::cast(callback);
4994 *holder = Handle<JSObject>(lookup.holder()); 4996 *holder = Handle<JSObject>(lookup.holder());
4995 return true; 4997 return true;
4996 } 4998 }
4997 4999
4998 // We haven't found a JavaScript accessor anywhere. 5000 // We haven't found a JavaScript accessor anywhere.
4999 return false; 5001 return false;
5000 } 5002 }
5001 5003
5002 5004
5003 static bool LookupSetter(Handle<Map> map, 5005 static bool LookupSetter(Handle<Map> map,
5004 Handle<String> name, 5006 Handle<String> name,
5005 Handle<JSFunction>* setter, 5007 Handle<JSFunction>* setter,
5006 Handle<JSObject>* holder) { 5008 Handle<JSObject>* holder,
5009 Zone* zone) {
5007 Handle<AccessorPair> accessors; 5010 Handle<AccessorPair> accessors;
5008 if (LookupAccessorPair(map, name, &accessors, holder) && 5011 if (LookupAccessorPair(map, name, &accessors, holder, zone) &&
5009 accessors->setter()->IsJSFunction()) { 5012 accessors->setter()->IsJSFunction()) {
5010 Handle<JSFunction> func(JSFunction::cast(accessors->setter())); 5013 Handle<JSFunction> func(JSFunction::cast(accessors->setter()));
5011 CallOptimization call_optimization(func); 5014 CallOptimization call_optimization(func);
5012 // TODO(dcarney): temporary hack unless crankshaft can handle api calls. 5015 // TODO(dcarney): temporary hack unless crankshaft can handle api calls.
5013 if (call_optimization.is_simple_api_call()) return false; 5016 if (call_optimization.is_simple_api_call()) return false;
5014 *setter = func; 5017 *setter = func;
5015 return true; 5018 return true;
5016 } 5019 }
5017 return false; 5020 return false;
5018 } 5021 }
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
5159 Handle<Map> map = property->GetReceiverType(); 5162 Handle<Map> map = property->GetReceiverType();
5160 Handle<String> name = property->key()->AsPropertyName(); 5163 Handle<String> name = property->key()->AsPropertyName();
5161 HInstruction* store; 5164 HInstruction* store;
5162 if (map.is_null()) { 5165 if (map.is_null()) {
5163 // If we don't know the monomorphic type, do a generic store. 5166 // If we don't know the monomorphic type, do a generic store.
5164 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); 5167 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value));
5165 } else { 5168 } else {
5166 #if DEBUG 5169 #if DEBUG
5167 Handle<JSFunction> setter; 5170 Handle<JSFunction> setter;
5168 Handle<JSObject> holder; 5171 Handle<JSObject> holder;
5169 ASSERT(!LookupSetter(map, name, &setter, &holder)); 5172 ASSERT(!LookupSetter(map, name, &setter, &holder, zone()));
5170 #endif 5173 #endif
5171 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, 5174 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
5172 name, 5175 name,
5173 value, 5176 value,
5174 map)); 5177 map));
5175 } 5178 }
5176 AddInstruction(store); 5179 AddInstruction(store);
5177 if (store->HasObservableSideEffects()) { 5180 if (store->HasObservableSideEffects()) {
5178 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5181 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
5179 } 5182 }
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
5442 HValue* value) { 5445 HValue* value) {
5443 return New<HStoreNamedGeneric>( 5446 return New<HStoreNamedGeneric>(
5444 object, 5447 object,
5445 name, 5448 name,
5446 value, 5449 value,
5447 function_strict_mode_flag()); 5450 function_strict_mode_flag());
5448 } 5451 }
5449 5452
5450 5453
5451 // Sets the lookup result and returns true if the load/store can be inlined. 5454 // Sets the lookup result and returns true if the load/store can be inlined.
5452 static bool ComputeStoreField(Handle<Map> type, 5455 static bool ComputeStoreField(Type* type,
5453 Handle<String> name, 5456 Handle<String> name,
5454 LookupResult* lookup, 5457 LookupResult* lookup,
5455 bool lookup_transition = true) { 5458 bool lookup_transition = true) {
5456 ASSERT(!type->is_observed()); 5459 if (!CanInlinePropertyAccess(type) || !type->IsClass()) {
5457 if (!CanInlinePropertyAccess(IC::MapToType(type))) {
5458 lookup->NotFound(); 5460 lookup->NotFound();
5459 return false; 5461 return false;
5460 } 5462 }
5463 Handle<Map> map = type->AsClass();
5464 ASSERT(!map->is_observed());
5461 // If we directly find a field, the access can be inlined. 5465 // If we directly find a field, the access can be inlined.
5462 type->LookupDescriptor(NULL, *name, lookup); 5466 map->LookupDescriptor(NULL, *name, lookup);
5463 if (lookup->IsField()) return true; 5467 if (lookup->IsField()) return true;
5464 5468
5465 if (!lookup_transition) return false; 5469 if (!lookup_transition) return false;
5466 5470
5467 type->LookupTransition(NULL, *name, lookup); 5471 map->LookupTransition(NULL, *name, lookup);
5468 return lookup->IsTransitionToField(*type) && 5472 return lookup->IsTransitionToField(*map) && map->unused_property_fields() > 0;
5469 (type->unused_property_fields() > 0);
5470 } 5473 }
5471 5474
5472 5475
5473 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( 5476 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic(
5474 HValue* object, 5477 HValue* object,
5475 Handle<String> name, 5478 Handle<String> name,
5476 HValue* value, 5479 HValue* value,
5477 Handle<Map> map) { 5480 Handle<Map> map) {
5478 // Handle a store to a known field. 5481 // Handle a store to a known field.
5479 LookupResult lookup(isolate()); 5482 LookupResult lookup(isolate());
5480 if (ComputeStoreField(map, name, &lookup)) { 5483 if (ComputeStoreField(ToType(map), name, &lookup)) {
5481 HCheckMaps* checked_object = AddCheckMap(object, map); 5484 HCheckMaps* checked_object = AddCheckMap(object, map);
5482 return BuildStoreNamedField(checked_object, name, value, map, &lookup); 5485 return BuildStoreNamedField(checked_object, name, value, map, &lookup);
5483 } 5486 }
5484 5487
5485 // No luck, do a generic store. 5488 // No luck, do a generic store.
5486 return BuildStoreNamedGeneric(object, name, value); 5489 return BuildStoreNamedGeneric(object, name, value);
5487 } 5490 }
5488 5491
5489 5492
5490 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatibleForLoad( 5493 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatibleForLoad(
5491 PropertyAccessInfo* info) { 5494 PropertyAccessInfo* info) {
5492 if (!CanInlinePropertyAccess(type_)) return false; 5495 if (!CanInlinePropertyAccess(type_)) return false;
5493 5496
5494 // Currently only handle HeapType::Number as a polymorphic case. 5497 // Currently only handle Type::Number as a polymorphic case.
5495 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 5498 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
5496 // instruction. 5499 // instruction.
5497 if (type_->Is(HeapType::Number())) return false; 5500 if (type_->Is(Type::Number())) return false;
5498 5501
5499 // Values are only compatible for monomorphic load if they all behave the same 5502 // Values are only compatible for monomorphic load if they all behave the same
5500 // regarding value wrappers. 5503 // regarding value wrappers.
5501 if (type_->Is(HeapType::NumberOrString())) { 5504 if (type_->Is(Type::NumberOrString())) {
5502 if (!info->type_->Is(HeapType::NumberOrString())) return false; 5505 if (!info->type_->Is(Type::NumberOrString())) return false;
5503 } else { 5506 } else {
5504 if (info->type_->Is(HeapType::NumberOrString())) return false; 5507 if (info->type_->Is(Type::NumberOrString())) return false;
5505 } 5508 }
5506 5509
5507 if (!LookupDescriptor()) return false; 5510 if (!LookupDescriptor()) return false;
5508 5511
5509 if (!lookup_.IsFound()) { 5512 if (!lookup_.IsFound()) {
5510 return (!info->lookup_.IsFound() || info->has_holder()) && 5513 return (!info->lookup_.IsFound() || info->has_holder()) &&
5511 map()->prototype() == info->map()->prototype(); 5514 map()->prototype() == info->map()->prototype();
5512 } 5515 }
5513 5516
5514 // Mismatch if the other access info found the property in the prototype 5517 // Mismatch if the other access info found the property in the prototype
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5565 5568
5566 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 5569 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
5567 Handle<Map> map = this->map(); 5570 Handle<Map> map = this->map();
5568 5571
5569 while (map->prototype()->IsJSObject()) { 5572 while (map->prototype()->IsJSObject()) {
5570 holder_ = handle(JSObject::cast(map->prototype())); 5573 holder_ = handle(JSObject::cast(map->prototype()));
5571 if (holder_->map()->is_deprecated()) { 5574 if (holder_->map()->is_deprecated()) {
5572 JSObject::TryMigrateInstance(holder_); 5575 JSObject::TryMigrateInstance(holder_);
5573 } 5576 }
5574 map = Handle<Map>(holder_->map()); 5577 map = Handle<Map>(holder_->map());
5575 if (!CanInlinePropertyAccess(IC::MapToType(map))) { 5578 if (!CanInlinePropertyAccess(ToType(map))) {
5576 lookup_.NotFound(); 5579 lookup_.NotFound();
5577 return false; 5580 return false;
5578 } 5581 }
5579 map->LookupDescriptor(*holder_, *name_, &lookup_); 5582 map->LookupDescriptor(*holder_, *name_, &lookup_);
5580 if (lookup_.IsFound()) return LoadResult(map); 5583 if (lookup_.IsFound()) return LoadResult(map);
5581 } 5584 }
5582 lookup_.NotFound(); 5585 lookup_.NotFound();
5583 return true; 5586 return true;
5584 } 5587 }
5585 5588
5586 5589
5587 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadMonomorphic() { 5590 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadMonomorphic() {
5588 if (!CanInlinePropertyAccess(type_)) return false; 5591 if (!CanInlinePropertyAccess(type_)) return false;
5589 if (IsJSObjectFieldAccessor()) return true; 5592 if (IsJSObjectFieldAccessor()) return true;
5590 if (!LookupDescriptor()) return false; 5593 if (!LookupDescriptor()) return false;
5591 if (lookup_.IsFound()) return true; 5594 if (lookup_.IsFound()) return true;
5592 return LookupInPrototypes(); 5595 return LookupInPrototypes();
5593 } 5596 }
5594 5597
5595 5598
5596 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic( 5599 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
5597 SmallMapList* types) { 5600 SmallMapList* types) {
5598 ASSERT(type_->Is(IC::MapToType(types->first()))); 5601 ASSERT(type_->Is(ToType(types->first())));
5599 if (!CanLoadMonomorphic()) return false; 5602 if (!CanLoadMonomorphic()) return false;
5600 if (types->length() > kMaxLoadPolymorphism) return false; 5603 if (types->length() > kMaxLoadPolymorphism) return false;
5601 5604
5602 if (IsArrayLength()) { 5605 if (IsArrayLength()) {
5603 bool is_fast = IsFastElementsKind(map()->elements_kind()); 5606 bool is_fast = IsFastElementsKind(map()->elements_kind());
5604 for (int i = 1; i < types->length(); ++i) { 5607 for (int i = 1; i < types->length(); ++i) {
5605 Handle<Map> test_map = types->at(i); 5608 Handle<Map> test_map = types->at(i);
5606 if (test_map->instance_type() != JS_ARRAY_TYPE) return false; 5609 if (test_map->instance_type() != JS_ARRAY_TYPE) return false;
5607 if (IsFastElementsKind(test_map->elements_kind()) != is_fast) { 5610 if (IsFastElementsKind(test_map->elements_kind()) != is_fast) {
5608 return false; 5611 return false;
5609 } 5612 }
5610 } 5613 }
5611 return true; 5614 return true;
5612 } 5615 }
5613 5616
5614 HObjectAccess access = HObjectAccess::ForMap(); // bogus default 5617 HObjectAccess access = HObjectAccess::ForMap(); // bogus default
5615 if (GetJSObjectFieldAccess(&access)) { 5618 if (GetJSObjectFieldAccess(&access)) {
5616 for (int i = 1; i < types->length(); ++i) { 5619 for (int i = 1; i < types->length(); ++i) {
5617 PropertyAccessInfo test_info( 5620 PropertyAccessInfo test_info(builder_, ToType(types->at(i)), name_);
5618 builder_, IC::MapToType(types->at(i)), name_);
5619 HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default 5621 HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default
5620 if (!test_info.GetJSObjectFieldAccess(&test_access)) return false; 5622 if (!test_info.GetJSObjectFieldAccess(&test_access)) return false;
5621 if (!access.Equals(test_access)) return false; 5623 if (!access.Equals(test_access)) return false;
5622 } 5624 }
5623 return true; 5625 return true;
5624 } 5626 }
5625 5627
5626 // Currently only handle HeapType::Number as a polymorphic case. 5628 // Currently only handle Type::Number as a polymorphic case.
5627 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 5629 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
5628 // instruction. 5630 // instruction.
5629 if (type_->Is(HeapType::Number())) return false; 5631 if (type_->Is(Type::Number())) return false;
5630 5632
5631 for (int i = 1; i < types->length(); ++i) { 5633 for (int i = 1; i < types->length(); ++i) {
5632 PropertyAccessInfo test_info(builder_, IC::MapToType(types->at(i)), name_); 5634 PropertyAccessInfo test_info(builder_, ToType(types->at(i)), name_);
5633 if (!test_info.IsCompatibleForLoad(this)) return false; 5635 if (!test_info.IsCompatibleForLoad(this)) return false;
5634 } 5636 }
5635 5637
5636 return true; 5638 return true;
5637 } 5639 }
5638 5640
5639 5641
5640 static bool NeedsWrappingFor(Handle<HeapType> type, Handle<JSFunction> target) { 5642 static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) {
5641 return type->Is(HeapType::NumberOrString()) && 5643 return type->Is(Type::NumberOrString()) &&
5642 target->shared()->is_classic_mode() && 5644 target->shared()->is_classic_mode() &&
5643 !target->shared()->native(); 5645 !target->shared()->native();
5644 } 5646 }
5645 5647
5646 5648
5647 HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic( 5649 HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic(
5648 PropertyAccessInfo* info, 5650 PropertyAccessInfo* info,
5649 HValue* object, 5651 HValue* object,
5650 HValue* checked_object, 5652 HValue* checked_object,
5651 BailoutId ast_id, 5653 BailoutId ast_id,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
5699 SmallMapList* types, 5701 SmallMapList* types,
5700 Handle<String> name) { 5702 Handle<String> name) {
5701 // Something did not match; must use a polymorphic load. 5703 // Something did not match; must use a polymorphic load.
5702 int count = 0; 5704 int count = 0;
5703 HBasicBlock* join = NULL; 5705 HBasicBlock* join = NULL;
5704 HBasicBlock* number_block = NULL; 5706 HBasicBlock* number_block = NULL;
5705 bool handled_string = false; 5707 bool handled_string = false;
5706 5708
5707 bool handle_smi = false; 5709 bool handle_smi = false;
5708 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 5710 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
5709 PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name); 5711 PropertyAccessInfo info(this, ToType(types->at(i)), name);
5710 if (info.type()->Is(HeapType::String())) { 5712 if (info.type()->Is(Type::String())) {
5711 if (handled_string) continue; 5713 if (handled_string) continue;
5712 handled_string = true; 5714 handled_string = true;
5713 } 5715 }
5714 if (info.CanLoadMonomorphic()) { 5716 if (info.CanLoadMonomorphic()) {
5715 count++; 5717 count++;
5716 if (info.type()->Is(HeapType::Number())) { 5718 if (info.type()->Is(Type::Number())) {
5717 handle_smi = true; 5719 handle_smi = true;
5718 break; 5720 break;
5719 } 5721 }
5720 } 5722 }
5721 } 5723 }
5722 5724
5723 count = 0; 5725 count = 0;
5724 HControlInstruction* smi_check = NULL; 5726 HControlInstruction* smi_check = NULL;
5725 handled_string = false; 5727 handled_string = false;
5726 5728
5727 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 5729 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
5728 PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name); 5730 PropertyAccessInfo info(this, ToType(types->at(i)), name);
5729 if (info.type()->Is(HeapType::String())) { 5731 if (info.type()->Is(Type::String())) {
5730 if (handled_string) continue; 5732 if (handled_string) continue;
5731 handled_string = true; 5733 handled_string = true;
5732 } 5734 }
5733 if (!info.CanLoadMonomorphic()) continue; 5735 if (!info.CanLoadMonomorphic()) continue;
5734 5736
5735 if (count == 0) { 5737 if (count == 0) {
5736 join = graph()->CreateBasicBlock(); 5738 join = graph()->CreateBasicBlock();
5737 if (handle_smi) { 5739 if (handle_smi) {
5738 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 5740 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock();
5739 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 5741 HBasicBlock* not_smi_block = graph()->CreateBasicBlock();
5740 number_block = graph()->CreateBasicBlock(); 5742 number_block = graph()->CreateBasicBlock();
5741 smi_check = New<HIsSmiAndBranch>( 5743 smi_check = New<HIsSmiAndBranch>(
5742 object, empty_smi_block, not_smi_block); 5744 object, empty_smi_block, not_smi_block);
5743 FinishCurrentBlock(smi_check); 5745 FinishCurrentBlock(smi_check);
5744 Goto(empty_smi_block, number_block); 5746 Goto(empty_smi_block, number_block);
5745 set_current_block(not_smi_block); 5747 set_current_block(not_smi_block);
5746 } else { 5748 } else {
5747 BuildCheckHeapObject(object); 5749 BuildCheckHeapObject(object);
5748 } 5750 }
5749 } 5751 }
5750 ++count; 5752 ++count;
5751 HBasicBlock* if_true = graph()->CreateBasicBlock(); 5753 HBasicBlock* if_true = graph()->CreateBasicBlock();
5752 HBasicBlock* if_false = graph()->CreateBasicBlock(); 5754 HBasicBlock* if_false = graph()->CreateBasicBlock();
5753 HUnaryControlInstruction* compare; 5755 HUnaryControlInstruction* compare;
5754 5756
5755 HValue* dependency; 5757 HValue* dependency;
5756 if (info.type()->Is(HeapType::Number())) { 5758 if (info.type()->Is(Type::Number())) {
5757 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 5759 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
5758 compare = New<HCompareMap>(object, heap_number_map, if_true, if_false); 5760 compare = New<HCompareMap>(object, heap_number_map, if_true, if_false);
5759 dependency = smi_check; 5761 dependency = smi_check;
5760 } else if (info.type()->Is(HeapType::String())) { 5762 } else if (info.type()->Is(Type::String())) {
5761 compare = New<HIsStringAndBranch>(object, if_true, if_false); 5763 compare = New<HIsStringAndBranch>(object, if_true, if_false);
5762 dependency = compare; 5764 dependency = compare;
5763 } else { 5765 } else {
5764 compare = New<HCompareMap>(object, info.map(), if_true, if_false); 5766 compare = New<HCompareMap>(object, info.map(), if_true, if_false);
5765 dependency = compare; 5767 dependency = compare;
5766 } 5768 }
5767 FinishCurrentBlock(compare); 5769 FinishCurrentBlock(compare);
5768 5770
5769 if (info.type()->Is(HeapType::Number())) { 5771 if (info.type()->Is(Type::Number())) {
5770 Goto(if_true, number_block); 5772 Goto(if_true, number_block);
5771 if_true = number_block; 5773 if_true = number_block;
5772 number_block->SetJoinId(ast_id); 5774 number_block->SetJoinId(ast_id);
5773 } 5775 }
5774 5776
5775 set_current_block(if_true); 5777 set_current_block(if_true);
5776 5778
5777 HInstruction* load = BuildLoadMonomorphic( 5779 HInstruction* load = BuildLoadMonomorphic(
5778 &info, object, dependency, ast_id, 5780 &info, object, dependency, ast_id,
5779 return_id, FLAG_polymorphic_inlining); 5781 return_id, FLAG_polymorphic_inlining);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5829 // for all maps. Requires special map check on the set of all handled maps. 5831 // for all maps. Requires special map check on the set of all handled maps.
5830 if (types->length() > kMaxStorePolymorphism) return false; 5832 if (types->length() > kMaxStorePolymorphism) return false;
5831 5833
5832 LookupResult lookup(isolate()); 5834 LookupResult lookup(isolate());
5833 int count; 5835 int count;
5834 Representation representation = Representation::None(); 5836 Representation representation = Representation::None();
5835 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 5837 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
5836 for (count = 0; count < types->length(); ++count) { 5838 for (count = 0; count < types->length(); ++count) {
5837 Handle<Map> map = types->at(count); 5839 Handle<Map> map = types->at(count);
5838 // Pass false to ignore transitions. 5840 // Pass false to ignore transitions.
5839 if (!ComputeStoreField(map, name, &lookup, false)) break; 5841 if (!ComputeStoreField(ToType(map), name, &lookup, false)) break;
5840 ASSERT(!map->is_observed()); 5842 ASSERT(!map->is_observed());
5841 5843
5842 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 5844 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
5843 Representation new_representation = new_access.representation(); 5845 Representation new_representation = new_access.representation();
5844 5846
5845 if (count == 0) { 5847 if (count == 0) {
5846 // First time through the loop; set access and representation. 5848 // First time through the loop; set access and representation.
5847 access = new_access; 5849 access = new_access;
5848 representation = new_representation; 5850 representation = new_representation;
5849 } else if (!representation.IsCompatibleForStore(new_representation)) { 5851 } else if (!representation.IsCompatibleForStore(new_representation)) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
5889 } 5891 }
5890 5892
5891 // TODO(ager): We should recognize when the prototype chains for different 5893 // TODO(ager): We should recognize when the prototype chains for different
5892 // maps are identical. In that case we can avoid repeatedly generating the 5894 // maps are identical. In that case we can avoid repeatedly generating the
5893 // same prototype map checks. 5895 // same prototype map checks.
5894 int count = 0; 5896 int count = 0;
5895 HBasicBlock* join = NULL; 5897 HBasicBlock* join = NULL;
5896 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 5898 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
5897 Handle<Map> map = types->at(i); 5899 Handle<Map> map = types->at(i);
5898 LookupResult lookup(isolate()); 5900 LookupResult lookup(isolate());
5899 if (ComputeStoreField(map, name, &lookup)) { 5901 if (ComputeStoreField(ToType(map), name, &lookup)) {
5900 if (count == 0) { 5902 if (count == 0) {
5901 BuildCheckHeapObject(object); 5903 BuildCheckHeapObject(object);
5902 join = graph()->CreateBasicBlock(); 5904 join = graph()->CreateBasicBlock();
5903 } 5905 }
5904 ++count; 5906 ++count;
5905 HBasicBlock* if_true = graph()->CreateBasicBlock(); 5907 HBasicBlock* if_true = graph()->CreateBasicBlock();
5906 HBasicBlock* if_false = graph()->CreateBasicBlock(); 5908 HBasicBlock* if_false = graph()->CreateBasicBlock();
5907 HCompareMap* compare = New<HCompareMap>(object, map, if_true, if_false); 5909 HCompareMap* compare = New<HCompareMap>(object, map, if_true, if_false);
5908 FinishCurrentBlock(compare); 5910 FinishCurrentBlock(compare);
5909 5911
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
5955 join->SetJoinId(assignment_id); 5957 join->SetJoinId(assignment_id);
5956 set_current_block(join); 5958 set_current_block(join);
5957 if (!ast_context()->IsEffect()) { 5959 if (!ast_context()->IsEffect()) {
5958 ast_context()->ReturnValue(Pop()); 5960 ast_context()->ReturnValue(Pop());
5959 } 5961 }
5960 } 5962 }
5961 5963
5962 5964
5963 static bool ComputeReceiverTypes(Expression* expr, 5965 static bool ComputeReceiverTypes(Expression* expr,
5964 HValue* receiver, 5966 HValue* receiver,
5965 SmallMapList** t) { 5967 SmallMapList** t,
5968 Zone* zone) {
5966 SmallMapList* types = expr->GetReceiverTypes(); 5969 SmallMapList* types = expr->GetReceiverTypes();
5967 *t = types; 5970 *t = types;
5968 bool monomorphic = expr->IsMonomorphic(); 5971 bool monomorphic = expr->IsMonomorphic();
5969 if (types != NULL && receiver->HasMonomorphicJSObjectType()) { 5972 if (types != NULL && receiver->HasMonomorphicJSObjectType()) {
5970 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); 5973 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap();
5971 types->FilterForPossibleTransitions(root_map); 5974 types->FilterForPossibleTransitions(root_map);
5972 monomorphic = types->length() == 1; 5975 monomorphic = types->length() == 1;
5973 } 5976 }
5974 return monomorphic && CanInlinePropertyAccess(IC::MapToType(types->first())); 5977 return monomorphic && CanInlinePropertyAccess(
5978 IC::MapToType<Type>(types->first(), zone));
5975 } 5979 }
5976 5980
5977 5981
5978 void HOptimizedGraphBuilder::BuildStore(Expression* expr, 5982 void HOptimizedGraphBuilder::BuildStore(Expression* expr,
5979 Property* prop, 5983 Property* prop,
5980 BailoutId ast_id, 5984 BailoutId ast_id,
5981 BailoutId return_id, 5985 BailoutId return_id,
5982 bool is_uninitialized) { 5986 bool is_uninitialized) {
5983 HValue* value = environment()->ExpressionStackAt(0); 5987 HValue* value = environment()->ExpressionStackAt(0);
5984 5988
(...skipping 19 matching lines...) Expand all
6004 Deoptimizer::SOFT); 6008 Deoptimizer::SOFT);
6005 } 6009 }
6006 6010
6007 Literal* key = prop->key()->AsLiteral(); 6011 Literal* key = prop->key()->AsLiteral();
6008 Handle<String> name = Handle<String>::cast(key->value()); 6012 Handle<String> name = Handle<String>::cast(key->value());
6009 ASSERT(!name.is_null()); 6013 ASSERT(!name.is_null());
6010 6014
6011 HInstruction* instr = NULL; 6015 HInstruction* instr = NULL;
6012 6016
6013 SmallMapList* types; 6017 SmallMapList* types;
6014 bool monomorphic = ComputeReceiverTypes(expr, object, &types); 6018 bool monomorphic = ComputeReceiverTypes(expr, object, &types, zone());
6015 6019
6016 if (monomorphic) { 6020 if (monomorphic) {
6017 Handle<Map> map = types->first(); 6021 Handle<Map> map = types->first();
6018 Handle<JSFunction> setter; 6022 Handle<JSFunction> setter;
6019 Handle<JSObject> holder; 6023 Handle<JSObject> holder;
6020 if (LookupSetter(map, name, &setter, &holder)) { 6024 if (LookupSetter(map, name, &setter, &holder, zone())) {
6021 AddCheckMap(object, map); 6025 AddCheckMap(object, map);
6022 AddCheckPrototypeMaps(holder, map); 6026 AddCheckPrototypeMaps(holder, map);
6023 bool needs_wrapping = NeedsWrappingFor(IC::MapToType(map), setter); 6027 bool needs_wrapping = NeedsWrappingFor(ToType(map), setter);
6024 bool try_inline = FLAG_inline_accessors && !needs_wrapping; 6028 bool try_inline = FLAG_inline_accessors && !needs_wrapping;
6025 if (try_inline && TryInlineSetter(setter, ast_id, return_id, value)) { 6029 if (try_inline && TryInlineSetter(setter, ast_id, return_id, value)) {
6026 return; 6030 return;
6027 } 6031 }
6028 Drop(2); 6032 Drop(2);
6029 Add<HPushArgument>(object); 6033 Add<HPushArgument>(object);
6030 Add<HPushArgument>(value); 6034 Add<HPushArgument>(value);
6031 if (needs_wrapping) { 6035 if (needs_wrapping) {
6032 HValue* function = Add<HConstant>(setter); 6036 HValue* function = Add<HConstant>(setter);
6033 instr = New<HCallFunction>(function, 2, WRAP_AND_CALL); 6037 instr = New<HCallFunction>(function, 2, WRAP_AND_CALL);
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
6693 HValue* obj, 6697 HValue* obj,
6694 HValue* key, 6698 HValue* key,
6695 HValue* val, 6699 HValue* val,
6696 Expression* expr, 6700 Expression* expr,
6697 bool is_store, 6701 bool is_store,
6698 bool* has_side_effects) { 6702 bool* has_side_effects) {
6699 ASSERT(!expr->IsPropertyName()); 6703 ASSERT(!expr->IsPropertyName());
6700 HInstruction* instr = NULL; 6704 HInstruction* instr = NULL;
6701 6705
6702 SmallMapList* types; 6706 SmallMapList* types;
6703 bool monomorphic = ComputeReceiverTypes(expr, obj, &types); 6707 bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
6704 6708
6705 bool force_generic = false; 6709 bool force_generic = false;
6706 if (is_store && (monomorphic || (types != NULL && !types->is_empty()))) { 6710 if (is_store && (monomorphic || (types != NULL && !types->is_empty()))) {
6707 // Stores can't be mono/polymorphic if their prototype chain has dictionary 6711 // Stores can't be mono/polymorphic if their prototype chain has dictionary
6708 // elements. However a receiver map that has dictionary elements itself 6712 // elements. However a receiver map that has dictionary elements itself
6709 // should be left to normal mono/poly behavior (the other maps may benefit 6713 // should be left to normal mono/poly behavior (the other maps may benefit
6710 // from highly optimized stores). 6714 // from highly optimized stores).
6711 for (int i = 0; i < types->length(); i++) { 6715 for (int i = 0; i < types->length(); i++) {
6712 Handle<Map> current_map = types->at(i); 6716 Handle<Map> current_map = types->at(i);
6713 if (current_map->DictionaryElementsInPrototypeChainOnly()) { 6717 if (current_map->DictionaryElementsInPrototypeChainOnly()) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
6875 } else if (expr->IsFunctionPrototype()) { 6879 } else if (expr->IsFunctionPrototype()) {
6876 HValue* function = Pop(); 6880 HValue* function = Pop();
6877 BuildCheckHeapObject(function); 6881 BuildCheckHeapObject(function);
6878 instr = New<HLoadFunctionPrototype>(function); 6882 instr = New<HLoadFunctionPrototype>(function);
6879 6883
6880 } else if (expr->key()->IsPropertyName()) { 6884 } else if (expr->key()->IsPropertyName()) {
6881 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 6885 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
6882 HValue* object = Pop(); 6886 HValue* object = Pop();
6883 6887
6884 SmallMapList* types; 6888 SmallMapList* types;
6885 ComputeReceiverTypes(expr, object, &types); 6889 ComputeReceiverTypes(expr, object, &types, zone());
6886 ASSERT(types != NULL); 6890 ASSERT(types != NULL);
6887 6891
6888 if (types->length() > 0) { 6892 if (types->length() > 0) {
6889 PropertyAccessInfo info(this, IC::MapToType(types->first()), name); 6893 PropertyAccessInfo info(this, ToType(types->first()), name);
6890 if (!info.CanLoadAsMonomorphic(types)) { 6894 if (!info.CanLoadAsMonomorphic(types)) {
6891 return HandlePolymorphicLoadNamedField( 6895 return HandlePolymorphicLoadNamedField(
6892 ast_id, expr->LoadId(), object, types, name); 6896 ast_id, expr->LoadId(), object, types, name);
6893 } 6897 }
6894 6898
6895 HValue* checked_object; 6899 HValue* checked_object;
6896 // HeapType::Number() is only supported by polymorphic load/call handling. 6900 // Type::Number() is only supported by polymorphic load/call handling.
6897 ASSERT(!info.type()->Is(HeapType::Number())); 6901 ASSERT(!info.type()->Is(Type::Number()));
6898 BuildCheckHeapObject(object); 6902 BuildCheckHeapObject(object);
6899 if (AreStringTypes(types)) { 6903 if (AreStringTypes(types)) {
6900 checked_object = 6904 checked_object =
6901 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 6905 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
6902 } else { 6906 } else {
6903 checked_object = Add<HCheckMaps>(object, types); 6907 checked_object = Add<HCheckMaps>(object, types);
6904 } 6908 }
6905 instr = BuildLoadMonomorphic( 6909 instr = BuildLoadMonomorphic(
6906 &info, object, checked_object, ast_id, expr->LoadId()); 6910 &info, object, checked_object, ast_id, expr->LoadId());
6907 if (instr == NULL) return; 6911 if (instr == NULL) return;
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
7087 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 7091 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
7088 FunctionSorter order[kMaxCallPolymorphism]; 7092 FunctionSorter order[kMaxCallPolymorphism];
7089 7093
7090 bool handle_smi = false; 7094 bool handle_smi = false;
7091 bool handled_string = false; 7095 bool handled_string = false;
7092 int ordered_functions = 0; 7096 int ordered_functions = 0;
7093 7097
7094 for (int i = 0; 7098 for (int i = 0;
7095 i < types->length() && ordered_functions < kMaxCallPolymorphism; 7099 i < types->length() && ordered_functions < kMaxCallPolymorphism;
7096 ++i) { 7100 ++i) {
7097 PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name); 7101 PropertyAccessInfo info(this, ToType(types->at(i)), name);
7098 if (info.CanLoadMonomorphic() && 7102 if (info.CanLoadMonomorphic() &&
7099 info.lookup()->IsConstant() && 7103 info.lookup()->IsConstant() &&
7100 info.constant()->IsJSFunction()) { 7104 info.constant()->IsJSFunction()) {
7101 if (info.type()->Is(HeapType::String())) { 7105 if (info.type()->Is(Type::String())) {
7102 if (handled_string) continue; 7106 if (handled_string) continue;
7103 handled_string = true; 7107 handled_string = true;
7104 } 7108 }
7105 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 7109 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
7106 if (info.type()->Is(HeapType::Number())) { 7110 if (info.type()->Is(Type::Number())) {
7107 handle_smi = true; 7111 handle_smi = true;
7108 } 7112 }
7109 expr->set_target(target); 7113 expr->set_target(target);
7110 order[ordered_functions++] = 7114 order[ordered_functions++] =
7111 FunctionSorter(i, 7115 FunctionSorter(i,
7112 expr->target()->shared()->profiler_ticks(), 7116 expr->target()->shared()->profiler_ticks(),
7113 InliningAstSize(expr->target()), 7117 InliningAstSize(expr->target()),
7114 expr->target()->shared()->SourceSize()); 7118 expr->target()->shared()->SourceSize());
7115 } 7119 }
7116 } 7120 }
7117 7121
7118 std::sort(order, order + ordered_functions); 7122 std::sort(order, order + ordered_functions);
7119 7123
7120 HBasicBlock* number_block = NULL; 7124 HBasicBlock* number_block = NULL;
7121 HBasicBlock* join = NULL; 7125 HBasicBlock* join = NULL;
7122 handled_string = false; 7126 handled_string = false;
7123 int count = 0; 7127 int count = 0;
7124 7128
7125 for (int fn = 0; fn < ordered_functions; ++fn) { 7129 for (int fn = 0; fn < ordered_functions; ++fn) {
7126 int i = order[fn].index(); 7130 int i = order[fn].index();
7127 PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name); 7131 PropertyAccessInfo info(this, ToType(types->at(i)), name);
7128 if (info.type()->Is(HeapType::String())) { 7132 if (info.type()->Is(Type::String())) {
7129 if (handled_string) continue; 7133 if (handled_string) continue;
7130 handled_string = true; 7134 handled_string = true;
7131 } 7135 }
7132 // Reloads the target. 7136 // Reloads the target.
7133 info.CanLoadMonomorphic(); 7137 info.CanLoadMonomorphic();
7134 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 7138 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
7135 7139
7136 expr->set_target(target); 7140 expr->set_target(target);
7137 if (count == 0) { 7141 if (count == 0) {
7138 // Only needed once. 7142 // Only needed once.
7139 join = graph()->CreateBasicBlock(); 7143 join = graph()->CreateBasicBlock();
7140 if (handle_smi) { 7144 if (handle_smi) {
7141 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 7145 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock();
7142 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 7146 HBasicBlock* not_smi_block = graph()->CreateBasicBlock();
7143 number_block = graph()->CreateBasicBlock(); 7147 number_block = graph()->CreateBasicBlock();
7144 FinishCurrentBlock(New<HIsSmiAndBranch>( 7148 FinishCurrentBlock(New<HIsSmiAndBranch>(
7145 receiver, empty_smi_block, not_smi_block)); 7149 receiver, empty_smi_block, not_smi_block));
7146 Goto(empty_smi_block, number_block); 7150 Goto(empty_smi_block, number_block);
7147 set_current_block(not_smi_block); 7151 set_current_block(not_smi_block);
7148 } else { 7152 } else {
7149 BuildCheckHeapObject(receiver); 7153 BuildCheckHeapObject(receiver);
7150 } 7154 }
7151 } 7155 }
7152 ++count; 7156 ++count;
7153 HBasicBlock* if_true = graph()->CreateBasicBlock(); 7157 HBasicBlock* if_true = graph()->CreateBasicBlock();
7154 HBasicBlock* if_false = graph()->CreateBasicBlock(); 7158 HBasicBlock* if_false = graph()->CreateBasicBlock();
7155 HUnaryControlInstruction* compare; 7159 HUnaryControlInstruction* compare;
7156 7160
7157 Handle<Map> map = info.map(); 7161 Handle<Map> map = info.map();
7158 if (info.type()->Is(HeapType::Number())) { 7162 if (info.type()->Is(Type::Number())) {
7159 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 7163 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
7160 compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false); 7164 compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false);
7161 } else if (info.type()->Is(HeapType::String())) { 7165 } else if (info.type()->Is(Type::String())) {
7162 compare = New<HIsStringAndBranch>(receiver, if_true, if_false); 7166 compare = New<HIsStringAndBranch>(receiver, if_true, if_false);
7163 } else { 7167 } else {
7164 compare = New<HCompareMap>(receiver, map, if_true, if_false); 7168 compare = New<HCompareMap>(receiver, map, if_true, if_false);
7165 } 7169 }
7166 FinishCurrentBlock(compare); 7170 FinishCurrentBlock(compare);
7167 7171
7168 if (info.type()->Is(HeapType::Number())) { 7172 if (info.type()->Is(Type::Number())) {
7169 Goto(if_true, number_block); 7173 Goto(if_true, number_block);
7170 if_true = number_block; 7174 if_true = number_block;
7171 number_block->SetJoinId(expr->id()); 7175 number_block->SetJoinId(expr->id());
7172 } 7176 }
7173 7177
7174 set_current_block(if_true); 7178 set_current_block(if_true);
7175 7179
7176 AddCheckPrototypeMaps(info.holder(), map); 7180 AddCheckPrototypeMaps(info.holder(), map);
7177 7181
7178 HValue* function = Add<HConstant>(expr->target()); 7182 HValue* function = Add<HConstant>(expr->target());
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
8106 Expression* callee = expr->expression(); 8110 Expression* callee = expr->expression();
8107 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 8111 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
8108 HInstruction* call = NULL; 8112 HInstruction* call = NULL;
8109 8113
8110 Property* prop = callee->AsProperty(); 8114 Property* prop = callee->AsProperty();
8111 if (prop != NULL) { 8115 if (prop != NULL) {
8112 CHECK_ALIVE(VisitForValue(prop->obj())); 8116 CHECK_ALIVE(VisitForValue(prop->obj()));
8113 HValue* receiver = Top(); 8117 HValue* receiver = Top();
8114 8118
8115 SmallMapList* types; 8119 SmallMapList* types;
8116 ComputeReceiverTypes(expr, receiver, &types); 8120 ComputeReceiverTypes(expr, receiver, &types, zone());
8117 8121
8118 if (prop->key()->IsPropertyName() && types->length() > 0) { 8122 if (prop->key()->IsPropertyName() && types->length() > 0) {
8119 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 8123 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
8120 PropertyAccessInfo info(this, IC::MapToType(types->first()), name); 8124 PropertyAccessInfo info(this, ToType(types->first()), name);
8121 if (!info.CanLoadAsMonomorphic(types)) { 8125 if (!info.CanLoadAsMonomorphic(types)) {
8122 HandlePolymorphicCallNamed(expr, receiver, types, name); 8126 HandlePolymorphicCallNamed(expr, receiver, types, name);
8123 return; 8127 return;
8124 } 8128 }
8125 } 8129 }
8126 8130
8127 HValue* key = NULL; 8131 HValue* key = NULL;
8128 if (!prop->key()->IsPropertyName()) { 8132 if (!prop->key()->IsPropertyName()) {
8129 CHECK_ALIVE(VisitForValue(prop->key())); 8133 CHECK_ALIVE(VisitForValue(prop->key()));
8130 key = Pop(); 8134 key = Pop();
(...skipping 21 matching lines...) Expand all
8152 if (FLAG_trace_inlining) { 8156 if (FLAG_trace_inlining) {
8153 PrintF("Inlining builtin "); 8157 PrintF("Inlining builtin ");
8154 known_function->ShortPrint(); 8158 known_function->ShortPrint();
8155 PrintF("\n"); 8159 PrintF("\n");
8156 } 8160 }
8157 return; 8161 return;
8158 } 8162 }
8159 if (TryInlineApiMethodCall(expr, receiver, map)) return; 8163 if (TryInlineApiMethodCall(expr, receiver, map)) return;
8160 8164
8161 // Wrap the receiver if necessary. 8165 // Wrap the receiver if necessary.
8162 if (NeedsWrappingFor(IC::MapToType(types->first()), known_function)) { 8166 if (NeedsWrappingFor(ToType(types->first()), known_function)) {
8163 // Since HWrapReceiver currently cannot actually wrap numbers and 8167 // Since HWrapReceiver currently cannot actually wrap numbers and
8164 // strings, use the regular CallFunctionStub for method calls to wrap 8168 // strings, use the regular CallFunctionStub for method calls to wrap
8165 // the receiver. 8169 // the receiver.
8166 // TODO(verwaest): Support creation of value wrappers directly in 8170 // TODO(verwaest): Support creation of value wrappers directly in
8167 // HWrapReceiver. 8171 // HWrapReceiver.
8168 call = New<HCallFunction>( 8172 call = New<HCallFunction>(
8169 function, argument_count, WRAP_AND_CALL); 8173 function, argument_count, WRAP_AND_CALL);
8170 } else if (TryInlineCall(expr)) { 8174 } else if (TryInlineCall(expr)) {
8171 return; 8175 return;
8172 } else { 8176 } else {
(...skipping 3202 matching lines...) Expand 10 before | Expand all | Expand 10 after
11375 if (ShouldProduceTraceOutput()) { 11379 if (ShouldProduceTraceOutput()) {
11376 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11380 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11377 } 11381 }
11378 11382
11379 #ifdef DEBUG 11383 #ifdef DEBUG
11380 graph_->Verify(false); // No full verify. 11384 graph_->Verify(false); // No full verify.
11381 #endif 11385 #endif
11382 } 11386 }
11383 11387
11384 } } // namespace v8::internal 11388 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698