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

Side by Side Diff: src/hydrogen.cc

Issue 137263021: Merge BuildLoad/StoreMonomorphic (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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') | no next file » | 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 5059 matching lines...) Expand 10 before | Expand all | Expand 10 after
5070 Handle<String> name = property->key()->AsPropertyName(); 5070 Handle<String> name = property->key()->AsPropertyName();
5071 HInstruction* store; 5071 HInstruction* store;
5072 if (map.is_null()) { 5072 if (map.is_null()) {
5073 // If we don't know the monomorphic type, do a generic store. 5073 // If we don't know the monomorphic type, do a generic store.
5074 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); 5074 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value));
5075 } else { 5075 } else {
5076 PropertyAccessInfo info(this, STORE, ToType(map), name); 5076 PropertyAccessInfo info(this, STORE, ToType(map), name);
5077 if (info.CanAccessMonomorphic()) { 5077 if (info.CanAccessMonomorphic()) {
5078 HValue* checked_literal = BuildCheckMap(literal, map); 5078 HValue* checked_literal = BuildCheckMap(literal, map);
5079 ASSERT(!info.lookup()->IsPropertyCallbacks()); 5079 ASSERT(!info.lookup()->IsPropertyCallbacks());
5080 store = BuildStoreMonomorphic( 5080 store = BuildMonomorphicAccess(
5081 &info, checked_literal, value, 5081 &info, literal, checked_literal, value,
5082 BailoutId::None(), BailoutId::None()); 5082 BailoutId::None(), BailoutId::None());
5083 } else { 5083 } else {
5084 CHECK_ALIVE( 5084 CHECK_ALIVE(
5085 store = BuildStoreNamedGeneric(literal, name, value)); 5085 store = BuildStoreNamedGeneric(literal, name, value));
5086 } 5086 }
5087 } 5087 }
5088 AddInstruction(store); 5088 AddInstruction(store);
5089 if (store->HasObservableSideEffects()) { 5089 if (store->HasObservableSideEffects()) {
5090 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5090 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
5091 } 5091 }
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
5512 } 5512 }
5513 5513
5514 5514
5515 static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) { 5515 static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) {
5516 return type->Is(Type::NumberOrString()) && 5516 return type->Is(Type::NumberOrString()) &&
5517 target->shared()->is_classic_mode() && 5517 target->shared()->is_classic_mode() &&
5518 !target->shared()->native(); 5518 !target->shared()->native();
5519 } 5519 }
5520 5520
5521 5521
5522 HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic( 5522 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
5523 PropertyAccessInfo* info, 5523 PropertyAccessInfo* info,
5524 HValue* object, 5524 HValue* object,
5525 HValue* checked_object, 5525 HValue* checked_object,
5526 HValue* value,
5526 BailoutId ast_id, 5527 BailoutId ast_id,
5527 BailoutId return_id, 5528 BailoutId return_id,
5528 bool can_inline_accessor) { 5529 bool can_inline_accessor) {
5529 5530
5530 HObjectAccess access = HObjectAccess::ForMap(); // bogus default 5531 HObjectAccess access = HObjectAccess::ForMap(); // bogus default
5531 if (info->GetJSObjectFieldAccess(&access)) { 5532 if (info->GetJSObjectFieldAccess(&access)) {
5532 return New<HLoadNamedField>( 5533 ASSERT(info->IsLoad());
5533 checked_object, static_cast<HValue*>(NULL), access); 5534 return New<HLoadNamedField>(object, checked_object, access);
5534 } 5535 }
5535 5536
5536 HValue* checked_holder = checked_object; 5537 HValue* checked_holder = checked_object;
5537 if (info->has_holder()) { 5538 if (info->has_holder()) {
5538 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 5539 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
5539 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 5540 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
5540 } 5541 }
5541 5542
5542 if (!info->lookup()->IsFound()) return graph()->GetConstantUndefined(); 5543 if (!info->lookup()->IsFound()) {
5544 ASSERT(info->IsLoad());
5545 return graph()->GetConstantUndefined();
5546 }
5543 5547
5544 if (info->lookup()->IsField()) { 5548 if (info->lookup()->IsField()) {
5545 return BuildLoadNamedField(checked_holder, info->access()); 5549 if (info->IsLoad()) {
5550 return BuildLoadNamedField(checked_holder, info->access());
5551 } else {
5552 return BuildStoreNamedField(info, checked_object, value);
5553 }
5554 }
5555
5556 if (info->lookup()->IsTransition()) {
5557 ASSERT(!info->IsLoad());
5558 return BuildStoreNamedField(info, checked_object, value);
5546 } 5559 }
5547 5560
5548 if (info->lookup()->IsPropertyCallbacks()) { 5561 if (info->lookup()->IsPropertyCallbacks()) {
5562 Push(checked_object);
5563 int argument_count = 1;
5564 if (!info->IsLoad()) {
5565 argument_count = 2;
5566 Push(value);
5567 }
5568
5549 if (NeedsWrappingFor(info->type(), info->accessor())) { 5569 if (NeedsWrappingFor(info->type(), info->accessor())) {
5550 HValue* function = Add<HConstant>(info->accessor()); 5570 HValue* function = Add<HConstant>(info->accessor());
5551 Add<HPushArgument>(checked_object); 5571 PushArgumentsFromEnvironment(argument_count);
5552 return New<HCallFunction>(function, 1, WRAP_AND_CALL); 5572 return New<HCallFunction>(function, argument_count, WRAP_AND_CALL);
5553 } else { 5573 } else if (FLAG_inline_accessors && can_inline_accessor) {
5554 Push(checked_object); 5574 bool success = info->IsLoad()
5555 if (FLAG_inline_accessors && 5575 ? TryInlineGetter(info->accessor(), ast_id, return_id)
5556 can_inline_accessor && 5576 : TryInlineSetter(info->accessor(), ast_id, return_id, value);
5557 TryInlineGetter(info->accessor(), ast_id, return_id)) { 5577 if (success) return NULL;
5558 return NULL;
5559 }
5560 Add<HPushArgument>(Pop());
5561 return BuildCallConstantFunction(info->accessor(), 1);
5562 } 5578 }
5579
5580 PushArgumentsFromEnvironment(argument_count);
5581 return BuildCallConstantFunction(info->accessor(), argument_count);
5563 } 5582 }
5564 5583
5565 ASSERT(info->lookup()->IsConstant()); 5584 ASSERT(info->lookup()->IsConstant());
5566 return New<HConstant>(info->constant()); 5585 if (info->IsLoad()) {
5586 return New<HConstant>(info->constant());
5587 } else {
5588 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
5589 }
5567 } 5590 }
5568 5591
5569 5592
5570 HInstruction* HOptimizedGraphBuilder::BuildStoreMonomorphic(
5571 PropertyAccessInfo* info,
5572 HValue* checked_object,
5573 HValue* value,
5574 BailoutId ast_id,
5575 BailoutId return_id,
5576 bool can_inline_accessor) {
5577 ASSERT(!info->IsJSObjectFieldAccessor());
5578
5579 if (info->has_holder()) {
5580 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
5581 BuildCheckPrototypeMaps(prototype, info->holder());
5582 }
5583
5584 if (info->lookup()->IsPropertyCallbacks()) {
5585 if (NeedsWrappingFor(info->type(), info->accessor())) {
5586 HValue* function = Add<HConstant>(info->accessor());
5587 Add<HPushArgument>(checked_object);
5588 Add<HPushArgument>(value);
5589 return New<HCallFunction>(function, 2, WRAP_AND_CALL);
5590 } else {
5591 Push(checked_object);
5592 Push(value);
5593 if (FLAG_inline_accessors &&
5594 can_inline_accessor &&
5595 TryInlineSetter(info->accessor(), ast_id, return_id, value)) {
5596 return NULL;
5597 }
5598 PushArgumentsFromEnvironment(2);
5599 return BuildCallConstantFunction(info->accessor(), 2);
5600 }
5601 }
5602
5603 if (info->lookup()->IsConstant()) {
5604 // Check whether we are trying to store the same constant.
5605 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
5606 }
5607
5608 ASSERT(info->lookup()->IsField() || info->lookup()->IsTransition());
5609 return BuildStoreNamedField(info, checked_object, value);
5610 }
5611
5612
5613 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( 5593 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
5614 PropertyAccessType access_type, 5594 PropertyAccessType access_type,
5615 BailoutId ast_id, 5595 BailoutId ast_id,
5616 BailoutId return_id, 5596 BailoutId return_id,
5617 HValue* object, 5597 HValue* object,
5618 HValue* value, 5598 HValue* value,
5619 SmallMapList* types, 5599 SmallMapList* types,
5620 Handle<String> name) { 5600 Handle<String> name) {
5621 // Something did not match; must use a polymorphic load. 5601 // Something did not match; must use a polymorphic load.
5622 int count = 0; 5602 int count = 0;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
5688 FinishCurrentBlock(compare); 5668 FinishCurrentBlock(compare);
5689 5669
5690 if (info.type()->Is(Type::Number())) { 5670 if (info.type()->Is(Type::Number())) {
5691 Goto(if_true, number_block); 5671 Goto(if_true, number_block);
5692 if_true = number_block; 5672 if_true = number_block;
5693 number_block->SetJoinId(ast_id); 5673 number_block->SetJoinId(ast_id);
5694 } 5674 }
5695 5675
5696 set_current_block(if_true); 5676 set_current_block(if_true);
5697 5677
5698 HInstruction* access = NULL; 5678 HInstruction* access = BuildMonomorphicAccess(
5679 &info, object, dependency, value, ast_id,
5680 return_id, FLAG_polymorphic_inlining);
5681
5699 HValue* result = NULL; 5682 HValue* result = NULL;
5700 switch (access_type) { 5683 switch (access_type) {
5701 case LOAD: 5684 case LOAD:
5702 access = BuildLoadMonomorphic(
5703 &info, object, dependency, ast_id,
5704 return_id, FLAG_polymorphic_inlining);
5705 result = access; 5685 result = access;
5706 break; 5686 break;
5707 case STORE: 5687 case STORE:
5708 access = BuildStoreMonomorphic(
5709 &info, dependency, value, ast_id, return_id,
5710 FLAG_polymorphic_inlining);
5711 result = value; 5688 result = value;
5712 break; 5689 break;
5713 } 5690 }
5714 5691
5715 if (access == NULL) { 5692 if (access == NULL) {
5716 if (HasStackOverflow()) return; 5693 if (HasStackOverflow()) return;
5717 } else { 5694 } else {
5718 if (!access->IsLinked()) AddInstruction(access); 5695 if (!access->IsLinked()) AddInstruction(access);
5719 if (!ast_context()->IsEffect()) Push(result); 5696 if (!ast_context()->IsEffect()) Push(result);
5720 } 5697 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
5837 5814
5838 ASSERT(!info.type()->Is(Type::Number())); 5815 ASSERT(!info.type()->Is(Type::Number()));
5839 BuildCheckHeapObject(object); 5816 BuildCheckHeapObject(object);
5840 HValue* checked_object; 5817 HValue* checked_object;
5841 if (AreStringTypes(types)) { 5818 if (AreStringTypes(types)) {
5842 checked_object = Add<HCheckInstanceType>( 5819 checked_object = Add<HCheckInstanceType>(
5843 object, HCheckInstanceType::IS_STRING); 5820 object, HCheckInstanceType::IS_STRING);
5844 } else { 5821 } else {
5845 checked_object = Add<HCheckMaps>(object, types); 5822 checked_object = Add<HCheckMaps>(object, types);
5846 } 5823 }
5847 instr = BuildStoreMonomorphic( 5824 instr = BuildMonomorphicAccess(
5848 &info, checked_object, value, ast_id, return_id); 5825 &info, object, checked_object, value, ast_id, return_id);
5849 if (instr == NULL) return; 5826 if (instr == NULL) return;
5850 ASSERT(!instr->IsLinked()); 5827 ASSERT(!instr->IsLinked());
5851 } else { 5828 } else {
5852 instr = BuildStoreNamedGeneric(object, name, value, is_uninitialized); 5829 instr = BuildStoreNamedGeneric(object, name, value, is_uninitialized);
5853 } 5830 }
5854 5831
5855 if (!ast_context()->IsEffect()) Push(value); 5832 if (!ast_context()->IsEffect()) Push(value);
5856 AddInstruction(instr); 5833 AddInstruction(instr);
5857 if (instr->HasObservableSideEffects()) { 5834 if (instr->HasObservableSideEffects()) {
5858 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 5835 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
(...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after
6690 HValue* checked_object; 6667 HValue* checked_object;
6691 // Type::Number() is only supported by polymorphic load/call handling. 6668 // Type::Number() is only supported by polymorphic load/call handling.
6692 ASSERT(!info.type()->Is(Type::Number())); 6669 ASSERT(!info.type()->Is(Type::Number()));
6693 BuildCheckHeapObject(object); 6670 BuildCheckHeapObject(object);
6694 if (AreStringTypes(types)) { 6671 if (AreStringTypes(types)) {
6695 checked_object = 6672 checked_object =
6696 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 6673 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
6697 } else { 6674 } else {
6698 checked_object = Add<HCheckMaps>(object, types); 6675 checked_object = Add<HCheckMaps>(object, types);
6699 } 6676 }
6700 instr = BuildLoadMonomorphic( 6677 instr = BuildMonomorphicAccess(
6701 &info, object, checked_object, ast_id, expr->LoadId()); 6678 &info, object, checked_object, NULL, ast_id, expr->LoadId());
6702 if (instr == NULL) return; 6679 if (instr == NULL) return;
6703 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); 6680 if (instr->IsLinked()) return ast_context()->ReturnValue(instr);
6704 } else { 6681 } else {
6705 instr = BuildLoadNamedGeneric(object, name, expr); 6682 instr = BuildLoadNamedGeneric(object, name, expr);
6706 } 6683 }
6707 6684
6708 } else { 6685 } else {
6709 HValue* key = Pop(); 6686 HValue* key = Pop();
6710 HValue* obj = Pop(); 6687 HValue* obj = Pop();
6711 6688
(...skipping 4459 matching lines...) Expand 10 before | Expand all | Expand 10 after
11171 if (ShouldProduceTraceOutput()) { 11148 if (ShouldProduceTraceOutput()) {
11172 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11149 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11173 } 11150 }
11174 11151
11175 #ifdef DEBUG 11152 #ifdef DEBUG
11176 graph_->Verify(false); // No full verify. 11153 graph_->Verify(false); // No full verify.
11177 #endif 11154 #endif
11178 } 11155 }
11179 11156
11180 } } // namespace v8::internal 11157 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698