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

Side by Side Diff: src/hydrogen.cc

Issue 153913002: A64: Synchronize with r16756. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: 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/hydrogen-alias-analysis.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 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 1027 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
1028 ASSERT(current_block() != NULL); 1028 ASSERT(current_block() != NULL);
1029 current_block()->AddInstruction(instr); 1029 current_block()->AddInstruction(instr);
1030 if (graph()->IsInsideNoSideEffectsScope()) { 1030 if (graph()->IsInsideNoSideEffectsScope()) {
1031 instr->SetFlag(HValue::kHasNoObservableSideEffects); 1031 instr->SetFlag(HValue::kHasNoObservableSideEffects);
1032 } 1032 }
1033 return instr; 1033 return instr;
1034 } 1034 }
1035 1035
1036 1036
1037 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter, 1037 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
1038 HValue* context) {
1039 if (FLAG_native_code_counters && counter->Enabled()) { 1038 if (FLAG_native_code_counters && counter->Enabled()) {
1040 HValue* reference = Add<HConstant>(ExternalReference(counter)); 1039 HValue* reference = Add<HConstant>(ExternalReference(counter));
1041 HValue* old_value = Add<HLoadNamedField>(reference, 1040 HValue* old_value = Add<HLoadNamedField>(reference,
1042 HObjectAccess::ForCounter()); 1041 HObjectAccess::ForCounter());
1043 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1()); 1042 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1());
1044 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1043 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
1045 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), 1044 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
1046 new_value); 1045 new_value);
1047 } 1046 }
1048 } 1047 }
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
1819 } 1818 }
1820 } 1819 }
1821 1820
1822 if_nil.CaptureContinuation(continuation); 1821 if_nil.CaptureContinuation(continuation);
1823 } 1822 }
1824 1823
1825 1824
1826 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object, 1825 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object,
1827 int previous_object_size, 1826 int previous_object_size,
1828 HValue* alloc_site) { 1827 HValue* alloc_site) {
1829 // TODO(mvstanton): ASSERT altered to CHECK to diagnose chromium bug 284577 1828 ASSERT(alloc_site != NULL);
1830 CHECK(alloc_site != NULL);
1831 HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>( 1829 HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>(
1832 previous_object, previous_object_size); 1830 previous_object, previous_object_size);
1833 Handle<Map> alloc_memento_map( 1831 Handle<Map> alloc_memento_map(
1834 isolate()->heap()->allocation_memento_map()); 1832 isolate()->heap()->allocation_memento_map());
1835 AddStoreMapConstant(alloc_memento, alloc_memento_map); 1833 AddStoreMapConstant(alloc_memento, alloc_memento_map);
1836 HObjectAccess access = HObjectAccess::ForAllocationMementoSite(); 1834 HObjectAccess access = HObjectAccess::ForAllocationMementoSite();
1837 Add<HStoreNamedField>(alloc_memento, access, alloc_site); 1835 Add<HStoreNamedField>(alloc_memento, access, alloc_site);
1838 return alloc_memento; 1836 return alloc_memento;
1839 } 1837 }
1840 1838
(...skipping 2159 matching lines...) Expand 10 before | Expand all | Expand 10 after
4000 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, 3998 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context,
4001 literals, 3999 literals,
4002 expr->pattern(), 4000 expr->pattern(),
4003 expr->flags(), 4001 expr->flags(),
4004 expr->literal_index()); 4002 expr->literal_index());
4005 return ast_context()->ReturnInstruction(instr, expr->id()); 4003 return ast_context()->ReturnInstruction(instr, expr->id());
4006 } 4004 }
4007 4005
4008 4006
4009 static bool CanInlinePropertyAccess(Map* type) { 4007 static bool CanInlinePropertyAccess(Map* type) {
4010 return !type->is_dictionary_map() && !type->has_named_interceptor(); 4008 return type->IsJSObjectMap() &&
4009 !type->is_dictionary_map() &&
4010 !type->has_named_interceptor();
4011 } 4011 }
4012 4012
4013 4013
4014 static void LookupInPrototypes(Handle<Map> map, 4014 static void LookupInPrototypes(Handle<Map> map,
4015 Handle<String> name, 4015 Handle<String> name,
4016 LookupResult* lookup) { 4016 LookupResult* lookup) {
4017 while (map->prototype()->IsJSObject()) { 4017 while (map->prototype()->IsJSObject()) {
4018 Handle<JSObject> holder(JSObject::cast(map->prototype())); 4018 Handle<JSObject> holder(JSObject::cast(map->prototype()));
4019 map = Handle<Map>(holder->map()); 4019 map = Handle<Map>(holder->map());
4020 if (!CanInlinePropertyAccess(*map)) break; 4020 if (!CanInlinePropertyAccess(*map)) break;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4165 HInstruction* literal; 4165 HInstruction* literal;
4166 4166
4167 // Check whether to use fast or slow deep-copying for boilerplate. 4167 // Check whether to use fast or slow deep-copying for boilerplate.
4168 int max_properties = kMaxFastLiteralProperties; 4168 int max_properties = kMaxFastLiteralProperties;
4169 Handle<Object> boilerplate(closure->literals()->get( 4169 Handle<Object> boilerplate(closure->literals()->get(
4170 expr->literal_index()), isolate()); 4170 expr->literal_index()), isolate());
4171 if (boilerplate->IsJSObject() && 4171 if (boilerplate->IsJSObject() &&
4172 IsFastLiteral(Handle<JSObject>::cast(boilerplate), 4172 IsFastLiteral(Handle<JSObject>::cast(boilerplate),
4173 kMaxFastLiteralDepth, 4173 kMaxFastLiteralDepth,
4174 &max_properties)) { 4174 &max_properties)) {
4175 Handle<JSObject> boilerplate_object = 4175 Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate);
4176 Handle<JSObject>::cast(boilerplate);
4177 4176
4178 literal = BuildFastLiteral(boilerplate_object, 4177 literal = BuildFastLiteral(boilerplate_object,
4179 Handle<Object>::null(), 4178 Handle<Object>::null(),
4180 DONT_TRACK_ALLOCATION_SITE); 4179 DONT_TRACK_ALLOCATION_SITE);
4181 } else { 4180 } else {
4182 NoObservableSideEffectsScope no_effects(this); 4181 NoObservableSideEffectsScope no_effects(this);
4183 Handle<FixedArray> closure_literals(closure->literals(), isolate()); 4182 Handle<FixedArray> closure_literals(closure->literals(), isolate());
4184 Handle<FixedArray> constant_properties = expr->constant_properties(); 4183 Handle<FixedArray> constant_properties = expr->constant_properties();
4185 int literal_index = expr->literal_index(); 4184 int literal_index = expr->literal_index();
4186 int flags = expr->fast_elements() 4185 int flags = expr->fast_elements()
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after
5129 5128
5130 case Variable::LOOKUP: 5129 case Variable::LOOKUP:
5131 return Bailout(kCompoundAssignmentToLookupSlot); 5130 return Bailout(kCompoundAssignmentToLookupSlot);
5132 } 5131 }
5133 return ast_context()->ReturnValue(Pop()); 5132 return ast_context()->ReturnValue(Pop());
5134 5133
5135 } else if (prop != NULL) { 5134 } else if (prop != NULL) {
5136 CHECK_ALIVE(VisitForValue(prop->obj())); 5135 CHECK_ALIVE(VisitForValue(prop->obj()));
5137 HValue* object = Top(); 5136 HValue* object = Top();
5138 HValue* key = NULL; 5137 HValue* key = NULL;
5139 if ((!prop->IsStringLength() && 5138 if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) ||
5140 !prop->IsFunctionPrototype() &&
5141 !prop->key()->IsPropertyName()) ||
5142 prop->IsStringAccess()) { 5139 prop->IsStringAccess()) {
5143 CHECK_ALIVE(VisitForValue(prop->key())); 5140 CHECK_ALIVE(VisitForValue(prop->key()));
5144 key = Top(); 5141 key = Top();
5145 } 5142 }
5146 5143
5147 CHECK_ALIVE(PushLoad(prop, object, key, expr->position())); 5144 CHECK_ALIVE(PushLoad(prop, object, key, expr->position()));
5148 5145
5149 CHECK_ALIVE(VisitForValue(expr->value())); 5146 CHECK_ALIVE(VisitForValue(expr->value()));
5150 HValue* right = Pop(); 5147 HValue* right = Pop();
5151 HValue* left = Pop(); 5148 HValue* left = Pop();
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
5376 HCheckMaps* checked_object = AddCheckMap(object, map); 5373 HCheckMaps* checked_object = AddCheckMap(object, map);
5377 return New<HLoadNamedField>( 5374 return New<HLoadNamedField>(
5378 checked_object, HObjectAccess::ForArrayLength(map->elements_kind())); 5375 checked_object, HObjectAccess::ForArrayLength(map->elements_kind()));
5379 } 5376 }
5380 } 5377 }
5381 5378
5382 LookupResult lookup(isolate()); 5379 LookupResult lookup(isolate());
5383 map->LookupDescriptor(NULL, *name, &lookup); 5380 map->LookupDescriptor(NULL, *name, &lookup);
5384 if (lookup.IsField()) { 5381 if (lookup.IsField()) {
5385 HCheckMaps* checked_object = AddCheckMap(object, map); 5382 HCheckMaps* checked_object = AddCheckMap(object, map);
5383 ASSERT(map->IsJSObjectMap());
5386 return BuildLoadNamedField( 5384 return BuildLoadNamedField(
5387 checked_object, HObjectAccess::ForField(map, &lookup, name)); 5385 checked_object, HObjectAccess::ForField(map, &lookup, name));
5388 } 5386 }
5389 5387
5390 // Handle a load of a constant known function. 5388 // Handle a load of a constant known function.
5391 if (lookup.IsConstant()) { 5389 if (lookup.IsConstant()) {
5392 AddCheckMap(object, map); 5390 AddCheckMap(object, map);
5393 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate()); 5391 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate());
5394 return New<HConstant>(constant); 5392 return New<HConstant>(constant);
5395 } 5393 }
5396 5394
5395 if (lookup.IsFound()) {
5396 // Cannot handle the property, do a generic load instead.
5397 HValue* context = environment()->context();
5398 return new(zone()) HLoadNamedGeneric(context, object, name);
5399 }
5400
5397 // Handle a load from a known field somewhere in the prototype chain. 5401 // Handle a load from a known field somewhere in the prototype chain.
5398 LookupInPrototypes(map, name, &lookup); 5402 LookupInPrototypes(map, name, &lookup);
5399 if (lookup.IsField()) { 5403 if (lookup.IsField()) {
5400 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5404 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5401 Handle<JSObject> holder(lookup.holder()); 5405 Handle<JSObject> holder(lookup.holder());
5402 Handle<Map> holder_map(holder->map()); 5406 Handle<Map> holder_map(holder->map());
5403 AddCheckMap(object, map); 5407 AddCheckMap(object, map);
5404 HValue* checked_holder = BuildCheckPrototypeMaps(prototype, holder); 5408 HValue* checked_holder = BuildCheckPrototypeMaps(prototype, holder);
5405 return BuildLoadNamedField( 5409 return BuildLoadNamedField(
5406 checked_holder, HObjectAccess::ForField(holder_map, &lookup, name)); 5410 checked_holder, HObjectAccess::ForField(holder_map, &lookup, name));
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
5479 // much faster than transitioning the elements to the worst case, trading a 5483 // much faster than transitioning the elements to the worst case, trading a
5480 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. 5484 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array.
5481 bool has_double_maps = false; 5485 bool has_double_maps = false;
5482 bool has_smi_or_object_maps = false; 5486 bool has_smi_or_object_maps = false;
5483 bool has_js_array_access = false; 5487 bool has_js_array_access = false;
5484 bool has_non_js_array_access = false; 5488 bool has_non_js_array_access = false;
5485 bool has_seen_holey_elements = false; 5489 bool has_seen_holey_elements = false;
5486 Handle<Map> most_general_consolidated_map; 5490 Handle<Map> most_general_consolidated_map;
5487 for (int i = 0; i < maps->length(); ++i) { 5491 for (int i = 0; i < maps->length(); ++i) {
5488 Handle<Map> map = maps->at(i); 5492 Handle<Map> map = maps->at(i);
5493 if (!map->IsJSObjectMap()) return NULL;
5489 // Don't allow mixing of JSArrays with JSObjects. 5494 // Don't allow mixing of JSArrays with JSObjects.
5490 if (map->instance_type() == JS_ARRAY_TYPE) { 5495 if (map->instance_type() == JS_ARRAY_TYPE) {
5491 if (has_non_js_array_access) return NULL; 5496 if (has_non_js_array_access) return NULL;
5492 has_js_array_access = true; 5497 has_js_array_access = true;
5493 } else if (has_js_array_access) { 5498 } else if (has_js_array_access) {
5494 return NULL; 5499 return NULL;
5495 } else { 5500 } else {
5496 has_non_js_array_access = true; 5501 has_non_js_array_access = true;
5497 } 5502 }
5498 // Don't allow mixed, incompatible elements kinds. 5503 // Don't allow mixed, incompatible elements kinds.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5531 consolidated_elements_kind, 5536 consolidated_elements_kind,
5532 false, NEVER_RETURN_HOLE, STANDARD_STORE); 5537 false, NEVER_RETURN_HOLE, STANDARD_STORE);
5533 return instr; 5538 return instr;
5534 } 5539 }
5535 5540
5536 5541
5537 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 5542 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
5538 HValue* object, 5543 HValue* object,
5539 HValue* key, 5544 HValue* key,
5540 HValue* val, 5545 HValue* val,
5541 Expression* prop, 5546 SmallMapList* maps,
5542 BailoutId ast_id, 5547 BailoutId ast_id,
5543 int position, 5548 int position,
5544 bool is_store, 5549 bool is_store,
5545 KeyedAccessStoreMode store_mode, 5550 KeyedAccessStoreMode store_mode,
5546 bool* has_side_effects) { 5551 bool* has_side_effects) {
5547 *has_side_effects = false; 5552 *has_side_effects = false;
5548 BuildCheckHeapObject(object); 5553 BuildCheckHeapObject(object);
5549 SmallMapList* maps = prop->GetReceiverTypes();
5550 5554
5551 if (!is_store) { 5555 if (!is_store) {
5552 HInstruction* consolidated_load = 5556 HInstruction* consolidated_load =
5553 TryBuildConsolidatedElementLoad(object, key, val, maps); 5557 TryBuildConsolidatedElementLoad(object, key, val, maps);
5554 if (consolidated_load != NULL) { 5558 if (consolidated_load != NULL) {
5555 *has_side_effects |= consolidated_load->HasObservableSideEffects(); 5559 *has_side_effects |= consolidated_load->HasObservableSideEffects();
5556 if (position != RelocInfo::kNoPosition) { 5560 if (position != RelocInfo::kNoPosition) {
5557 consolidated_load->set_position(position); 5561 consolidated_load->set_position(position);
5558 } 5562 }
5559 return consolidated_load; 5563 return consolidated_load;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5595 untransitionable_maps.Add(map); 5599 untransitionable_maps.Add(map);
5596 } 5600 }
5597 } 5601 }
5598 5602
5599 // If only one map is left after transitioning, handle this case 5603 // If only one map is left after transitioning, handle this case
5600 // monomorphically. 5604 // monomorphically.
5601 ASSERT(untransitionable_maps.length() >= 1); 5605 ASSERT(untransitionable_maps.length() >= 1);
5602 if (untransitionable_maps.length() == 1) { 5606 if (untransitionable_maps.length() == 1) {
5603 Handle<Map> untransitionable_map = untransitionable_maps[0]; 5607 Handle<Map> untransitionable_map = untransitionable_maps[0];
5604 HInstruction* instr = NULL; 5608 HInstruction* instr = NULL;
5605 if (untransitionable_map->has_slow_elements_kind()) { 5609 if (untransitionable_map->has_slow_elements_kind() ||
5610 !untransitionable_map->IsJSObjectMap()) {
5606 instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val) 5611 instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val)
5607 : BuildLoadKeyedGeneric(object, key)); 5612 : BuildLoadKeyedGeneric(object, key));
5608 } else { 5613 } else {
5609 instr = BuildMonomorphicElementAccess( 5614 instr = BuildMonomorphicElementAccess(
5610 object, key, val, transition, untransitionable_map, is_store, 5615 object, key, val, transition, untransitionable_map, is_store,
5611 store_mode); 5616 store_mode);
5612 } 5617 }
5613 *has_side_effects |= instr->HasObservableSideEffects(); 5618 *has_side_effects |= instr->HasObservableSideEffects();
5614 if (position != RelocInfo::kNoPosition) instr->set_position(position); 5619 if (position != RelocInfo::kNoPosition) instr->set_position(position);
5615 return is_store ? NULL : instr; 5620 return is_store ? NULL : instr;
5616 } 5621 }
5617 5622
5618 HBasicBlock* join = graph()->CreateBasicBlock(); 5623 HBasicBlock* join = graph()->CreateBasicBlock();
5619 5624
5620 for (int i = 0; i < untransitionable_maps.length(); ++i) { 5625 for (int i = 0; i < untransitionable_maps.length(); ++i) {
5621 Handle<Map> map = untransitionable_maps[i]; 5626 Handle<Map> map = untransitionable_maps[i];
5627 if (!map->IsJSObjectMap()) continue;
5622 ElementsKind elements_kind = map->elements_kind(); 5628 ElementsKind elements_kind = map->elements_kind();
5623 HBasicBlock* this_map = graph()->CreateBasicBlock(); 5629 HBasicBlock* this_map = graph()->CreateBasicBlock();
5624 HBasicBlock* other_map = graph()->CreateBasicBlock(); 5630 HBasicBlock* other_map = graph()->CreateBasicBlock();
5625 HCompareMap* mapcompare = 5631 HCompareMap* mapcompare =
5626 new(zone()) HCompareMap(object, map, this_map, other_map); 5632 new(zone()) HCompareMap(object, map, this_map, other_map);
5627 current_block()->Finish(mapcompare); 5633 current_block()->Finish(mapcompare);
5628 5634
5629 set_current_block(this_map); 5635 set_current_block(this_map);
5630 HInstruction* access = NULL; 5636 HInstruction* access = NULL;
5631 if (IsDictionaryElementsKind(elements_kind)) { 5637 if (IsDictionaryElementsKind(elements_kind)) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
5684 Handle<Map> map = types->first(); 5690 Handle<Map> map = types->first();
5685 if (map->has_slow_elements_kind()) { 5691 if (map->has_slow_elements_kind()) {
5686 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) 5692 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val)
5687 : BuildLoadKeyedGeneric(obj, key); 5693 : BuildLoadKeyedGeneric(obj, key);
5688 AddInstruction(instr); 5694 AddInstruction(instr);
5689 } else { 5695 } else {
5690 BuildCheckHeapObject(obj); 5696 BuildCheckHeapObject(obj);
5691 instr = BuildMonomorphicElementAccess( 5697 instr = BuildMonomorphicElementAccess(
5692 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); 5698 obj, key, val, NULL, map, is_store, expr->GetStoreMode());
5693 } 5699 }
5694 } else if (expr->GetReceiverTypes() != NULL && 5700 } else if (types != NULL && !types->is_empty()) {
5695 !expr->GetReceiverTypes()->is_empty()) {
5696 return HandlePolymorphicElementAccess( 5701 return HandlePolymorphicElementAccess(
5697 obj, key, val, expr, ast_id, position, is_store, 5702 obj, key, val, types, ast_id, position, is_store,
5698 expr->GetStoreMode(), has_side_effects); 5703 expr->GetStoreMode(), has_side_effects);
5699 } else { 5704 } else {
5700 if (is_store) { 5705 if (is_store) {
5701 if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized()) { 5706 if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized()) {
5702 Add<HDeoptimize>("Insufficient type feedback for keyed store", 5707 Add<HDeoptimize>("Insufficient type feedback for keyed store",
5703 Deoptimizer::SOFT); 5708 Deoptimizer::SOFT);
5704 } 5709 }
5705 instr = BuildStoreKeyedGeneric(obj, key, val); 5710 instr = BuildStoreKeyedGeneric(obj, key, val);
5706 } else { 5711 } else {
5707 if (expr->AsProperty()->IsUninitialized()) { 5712 if (expr->AsProperty()->IsUninitialized()) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
5813 HValue* object, 5818 HValue* object,
5814 HValue* key, 5819 HValue* key,
5815 int position) { 5820 int position) {
5816 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 5821 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
5817 Push(object); 5822 Push(object);
5818 if (key != NULL) Push(key); 5823 if (key != NULL) Push(key);
5819 BuildLoad(expr, position, expr->LoadId()); 5824 BuildLoad(expr, position, expr->LoadId());
5820 } 5825 }
5821 5826
5822 5827
5828 static bool AreStringTypes(SmallMapList* types) {
5829 if (types == NULL || types->length() == 0) return false;
5830 for (int i = 0; i < types->length(); i++) {
5831 if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
5832 }
5833 return true;
5834 }
5835
5836
5823 void HOptimizedGraphBuilder::BuildLoad(Property* expr, 5837 void HOptimizedGraphBuilder::BuildLoad(Property* expr,
5824 int position, 5838 int position,
5825 BailoutId ast_id) { 5839 BailoutId ast_id) {
5826 HInstruction* instr = NULL; 5840 HInstruction* instr = NULL;
5827 if (expr->IsStringLength()) { 5841 if (expr->IsStringAccess()) {
5828 HValue* string = Pop();
5829 BuildCheckHeapObject(string);
5830 HInstruction* checkstring =
5831 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
5832 instr = BuildLoadStringLength(string, checkstring);
5833 } else if (expr->IsStringAccess()) {
5834 HValue* index = Pop(); 5842 HValue* index = Pop();
5835 HValue* string = Pop(); 5843 HValue* string = Pop();
5836 HValue* context = environment()->context(); 5844 HValue* context = environment()->context();
5837 HInstruction* char_code = 5845 HInstruction* char_code =
5838 BuildStringCharCodeAt(string, index); 5846 BuildStringCharCodeAt(string, index);
5839 AddInstruction(char_code); 5847 AddInstruction(char_code);
5840 instr = HStringCharFromCode::New(zone(), context, char_code); 5848 instr = HStringCharFromCode::New(zone(), context, char_code);
5841 5849
5842 } else if (expr->IsFunctionPrototype()) { 5850 } else if (expr->IsFunctionPrototype()) {
5843 HValue* function = Pop(); 5851 HValue* function = Pop();
(...skipping 15 matching lines...) Expand all
5859 AddCheckConstantFunction(holder, Top(), map); 5867 AddCheckConstantFunction(holder, Top(), map);
5860 if (FLAG_inline_accessors && 5868 if (FLAG_inline_accessors &&
5861 TryInlineGetter(getter, ast_id, expr->LoadId())) { 5869 TryInlineGetter(getter, ast_id, expr->LoadId())) {
5862 return; 5870 return;
5863 } 5871 }
5864 Add<HPushArgument>(Pop()); 5872 Add<HPushArgument>(Pop());
5865 instr = new(zone()) HCallConstantFunction(getter, 1); 5873 instr = new(zone()) HCallConstantFunction(getter, 1);
5866 } else { 5874 } else {
5867 instr = BuildLoadNamedMonomorphic(Pop(), name, map); 5875 instr = BuildLoadNamedMonomorphic(Pop(), name, map);
5868 } 5876 }
5877 } else if (AreStringTypes(types) &&
5878 name->Equals(isolate()->heap()->length_string())) {
5879 BuildCheckHeapObject(Pop());
5880 HValue* checked_object =
5881 AddInstruction(HCheckInstanceType::NewIsString(object, zone()));
5882 instr = BuildLoadStringLength(object, checked_object);
5869 } else if (types != NULL && types->length() > 1) { 5883 } else if (types != NULL && types->length() > 1) {
5870 return HandlePolymorphicLoadNamedField( 5884 return HandlePolymorphicLoadNamedField(
5871 position, ast_id, Pop(), types, name); 5885 position, ast_id, Pop(), types, name);
5872 } else { 5886 } else {
5873 instr = BuildLoadNamedGeneric(Pop(), name, expr); 5887 instr = BuildLoadNamedGeneric(Pop(), name, expr);
5874 } 5888 }
5875 5889
5876 } else { 5890 } else {
5877 HValue* key = Pop(); 5891 HValue* key = Pop();
5878 HValue* obj = Pop(); 5892 HValue* obj = Pop();
(...skipping 20 matching lines...) Expand all
5899 5913
5900 5914
5901 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { 5915 void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
5902 ASSERT(!HasStackOverflow()); 5916 ASSERT(!HasStackOverflow());
5903 ASSERT(current_block() != NULL); 5917 ASSERT(current_block() != NULL);
5904 ASSERT(current_block()->HasPredecessor()); 5918 ASSERT(current_block()->HasPredecessor());
5905 5919
5906 if (TryArgumentsAccess(expr)) return; 5920 if (TryArgumentsAccess(expr)) return;
5907 5921
5908 CHECK_ALIVE(VisitForValue(expr->obj())); 5922 CHECK_ALIVE(VisitForValue(expr->obj()));
5909 if ((!expr->IsStringLength() && 5923 if ((!expr->IsFunctionPrototype() && !expr->key()->IsPropertyName()) ||
5910 !expr->IsFunctionPrototype() &&
5911 !expr->key()->IsPropertyName()) ||
5912 expr->IsStringAccess()) { 5924 expr->IsStringAccess()) {
5913 CHECK_ALIVE(VisitForValue(expr->key())); 5925 CHECK_ALIVE(VisitForValue(expr->key()));
5914 } 5926 }
5915 5927
5916 BuildLoad(expr, expr->position(), expr->id()); 5928 BuildLoad(expr, expr->position(), expr->id());
5917 } 5929 }
5918 5930
5919 5931
5920 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant, 5932 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
5921 CompilationInfo* info) { 5933 CompilationInfo* info) {
(...skipping 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after
7552 } 7564 }
7553 7565
7554 // Argument of the count operation is a property. 7566 // Argument of the count operation is a property.
7555 ASSERT(prop != NULL); 7567 ASSERT(prop != NULL);
7556 if (returns_original_input) Push(graph()->GetConstantUndefined()); 7568 if (returns_original_input) Push(graph()->GetConstantUndefined());
7557 7569
7558 CHECK_ALIVE(VisitForValue(prop->obj())); 7570 CHECK_ALIVE(VisitForValue(prop->obj()));
7559 HValue* object = Top(); 7571 HValue* object = Top();
7560 7572
7561 HValue* key = NULL; 7573 HValue* key = NULL;
7562 if ((!prop->IsStringLength() && 7574 if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) ||
7563 !prop->IsFunctionPrototype() &&
7564 !prop->key()->IsPropertyName()) ||
7565 prop->IsStringAccess()) { 7575 prop->IsStringAccess()) {
7566 CHECK_ALIVE(VisitForValue(prop->key())); 7576 CHECK_ALIVE(VisitForValue(prop->key()));
7567 key = Top(); 7577 key = Top();
7568 } 7578 }
7569 7579
7570 CHECK_ALIVE(PushLoad(prop, object, key, expr->position())); 7580 CHECK_ALIVE(PushLoad(prop, object, key, expr->position()));
7571 7581
7572 after = BuildIncrement(returns_original_input, expr); 7582 after = BuildIncrement(returns_original_input, expr);
7573 7583
7574 if (returns_original_input) { 7584 if (returns_original_input) {
(...skipping 29 matching lines...) Expand all
7604 BuildCheckHeapObject(string); 7614 BuildCheckHeapObject(string);
7605 HValue* checkstring = 7615 HValue* checkstring =
7606 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 7616 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
7607 HInstruction* length = BuildLoadStringLength(string, checkstring); 7617 HInstruction* length = BuildLoadStringLength(string, checkstring);
7608 AddInstruction(length); 7618 AddInstruction(length);
7609 HInstruction* checked_index = Add<HBoundsCheck>(index, length); 7619 HInstruction* checked_index = Add<HBoundsCheck>(index, length);
7610 return New<HStringCharCodeAt>(string, checked_index); 7620 return New<HStringCharCodeAt>(string, checked_index);
7611 } 7621 }
7612 7622
7613 7623
7614 // Checks if the given shift amounts have form: (sa) and (32 - sa). 7624 // Checks if the given shift amounts have following forms:
7625 // (N1) and (N2) with N1 + N2 = 32; (sa) and (32 - sa).
7615 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 7626 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
7616 HValue* const32_minus_sa) { 7627 HValue* const32_minus_sa) {
7628 if (sa->IsConstant() && const32_minus_sa->IsConstant()) {
7629 const HConstant* c1 = HConstant::cast(sa);
7630 const HConstant* c2 = HConstant::cast(const32_minus_sa);
7631 return c1->HasInteger32Value() && c2->HasInteger32Value() &&
7632 (c1->Integer32Value() + c2->Integer32Value() == 32);
7633 }
7617 if (!const32_minus_sa->IsSub()) return false; 7634 if (!const32_minus_sa->IsSub()) return false;
7618 HSub* sub = HSub::cast(const32_minus_sa); 7635 HSub* sub = HSub::cast(const32_minus_sa);
7619 if (sa != sub->right()) return false; 7636 if (sa != sub->right()) return false;
7620 HValue* const32 = sub->left(); 7637 HValue* const32 = sub->left();
7621 if (!const32->IsConstant() || 7638 if (!const32->IsConstant() ||
7622 HConstant::cast(const32)->Integer32Value() != 32) { 7639 HConstant::cast(const32)->Integer32Value() != 32) {
7623 return false; 7640 return false;
7624 } 7641 }
7625 return (sub->right() == sa); 7642 return (sub->right() == sa);
7626 } 7643 }
(...skipping 2055 matching lines...) Expand 10 before | Expand all | Expand 10 after
9682 if (ShouldProduceTraceOutput()) { 9699 if (ShouldProduceTraceOutput()) {
9683 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9700 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9684 } 9701 }
9685 9702
9686 #ifdef DEBUG 9703 #ifdef DEBUG
9687 graph_->Verify(false); // No full verify. 9704 graph_->Verify(false); // No full verify.
9688 #endif 9705 #endif
9689 } 9706 }
9690 9707
9691 } } // namespace v8::internal 9708 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-alias-analysis.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698