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

Side by Side Diff: src/hydrogen.cc

Issue 22213002: Replace LoadNamedFieldPolymorphic with explicit branches. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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/arm/lithium-codegen-arm.cc ('k') | src/hydrogen-instructions.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 4595 matching lines...) Expand 10 before | Expand all | Expand 10 after
4606 4606
4607 Handle<JSObject> holder(lookup.holder()); 4607 Handle<JSObject> holder(lookup.holder());
4608 Handle<Map> holder_map(holder->map()); 4608 Handle<Map> holder_map(holder->map());
4609 BuildCheckPrototypeMaps(Handle<JSObject>::cast(prototype), holder); 4609 BuildCheckPrototypeMaps(Handle<JSObject>::cast(prototype), holder);
4610 HValue* holder_value = Add<HConstant>(holder); 4610 HValue* holder_value = Add<HConstant>(holder);
4611 return BuildLoadNamedField(holder_value, 4611 return BuildLoadNamedField(holder_value,
4612 HObjectAccess::ForField(holder_map, &lookup, name)); 4612 HObjectAccess::ForField(holder_map, &lookup, name));
4613 } 4613 }
4614 4614
4615 4615
4616 // Returns true if an instance of this map can never find a property with this
4617 // name in its prototype chain. This means all prototypes up to the top are
4618 // fast and don't have the name in them. It would be good if we could optimize
4619 // polymorphic loads where the property is sometimes found in the prototype
4620 // chain.
4621 static bool PrototypeChainCanNeverResolve(
4622 Handle<Map> map, Handle<String> name) {
4623 Isolate* isolate = map->GetIsolate();
4624 Object* current = map->prototype();
4625 while (current != isolate->heap()->null_value()) {
4626 if (current->IsJSGlobalProxy() ||
4627 current->IsGlobalObject() ||
4628 !current->IsJSObject() ||
4629 JSObject::cast(current)->map()->has_named_interceptor() ||
4630 JSObject::cast(current)->IsAccessCheckNeeded() ||
4631 !JSObject::cast(current)->HasFastProperties()) {
4632 return false;
4633 }
4634
4635 LookupResult lookup(isolate);
4636 Map* map = JSObject::cast(current)->map();
4637 map->LookupDescriptor(NULL, *name, &lookup);
4638 if (lookup.IsFound()) return false;
4639 if (!lookup.IsCacheable()) return false;
4640 current = JSObject::cast(current)->GetPrototype();
4641 }
4642 return true;
4643 }
4644
4645
4616 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 4646 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
4617 Property* expr, 4647 Property* expr,
4618 HValue* object, 4648 HValue* object,
4619 SmallMapList* types, 4649 SmallMapList* types,
4620 Handle<String> name) { 4650 Handle<String> name) {
4621 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( 4651 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
4622 expr, object, types, name); 4652 expr, object, types, name);
4623 if (instr == NULL) { 4653 if (instr != NULL) {
4624 // Something did not match; must use a polymorphic load. 4654 instr->set_position(expr->position());
4625 BuildCheckHeapObject(object); 4655 return ast_context()->ReturnInstruction(instr, expr->id());
4626 HValue* context = environment()->context();
4627 instr = new(zone()) HLoadNamedFieldPolymorphic(
4628 context, object, types, name, zone());
4629 } 4656 }
4630 4657
4631 instr->set_position(expr->position()); 4658 NoObservableSideEffectsScope no_side_effects(this);
ulan 2013/08/06 13:36:24 Shouldn't this be in its own scope (i.e. surrounde
4632 return ast_context()->ReturnInstruction(instr, expr->id()); 4659 // Something did not match; must use a polymorphic load.
4660 int count = 0;
4661 HBasicBlock* join = NULL;
4662 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
4663 Handle<Map> map = types->at(i);
4664 LookupResult lookup(isolate());
4665 if (ComputeLoadStoreField(map, name, &lookup, false) ||
4666 (lookup.IsCacheable() &&
4667 !map->is_dictionary_map() &&
4668 !map->has_named_interceptor() &&
4669 (lookup.IsConstant() ||
4670 (!lookup.IsFound() &&
4671 PrototypeChainCanNeverResolve(map, name))))) {
4672 if (count == 0) {
4673 BuildCheckHeapObject(object);
4674 join = graph()->CreateBasicBlock();
4675 }
4676 ++count;
4677 HBasicBlock* if_true = graph()->CreateBasicBlock();
4678 HBasicBlock* if_false = graph()->CreateBasicBlock();
4679 HCompareMap* compare =
4680 new(zone()) HCompareMap(object, map, if_true, if_false);
4681 current_block()->Finish(compare);
4682
4683 set_current_block(if_true);
4684
4685 // TODO(verwaest): Merge logic with BuildLoadNamedMonomorphic.
4686 if (lookup.IsField()) {
4687 HObjectAccess access = HObjectAccess::ForField(map, &lookup, name);
4688 HLoadNamedField* load = BuildLoadNamedField(object, access);
4689 load->set_position(expr->position());
4690 AddInstruction(load);
4691 Push(load);
4692 } else if (lookup.IsConstant()) {
4693 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate());
4694 HConstant* hconstant = Add<HConstant>(constant);
4695 Push(hconstant);
4696 } else {
4697 ASSERT(!lookup.IsFound());
4698 if (map->prototype()->IsJSObject()) {
4699 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
4700 Handle<JSObject> holder = prototype;
4701 while (holder->map()->prototype()->IsJSObject()) {
4702 holder = handle(JSObject::cast(holder->map()->prototype()));
4703 }
4704 BuildCheckPrototypeMaps(prototype, holder);
4705 }
4706 Push(graph()->GetConstantUndefined());
4707 }
4708
4709 current_block()->Goto(join, NULL, false);
4710 set_current_block(if_false);
4711 }
4712 }
4713
4714 // Finish up. Unconditionally deoptimize if we've handled all the maps we
4715 // know about and do not want to handle ones we've never seen. Otherwise
4716 // use a generic IC.
4717 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
4718 FinishExitWithHardDeoptimization(join);
4719 } else {
4720 HInstruction* load = BuildLoadNamedGeneric(object, name, expr);
ulan 2013/08/06 13:36:24 Why it is in NoObservableSideEffectsScope scope?
Toon Verwaest 2013/08/06 14:03:44 Scary premature optimization attempt. Removed :)
4721 load->set_position(expr->position());
4722 AddInstruction(load);
4723 Push(load);
4724
4725 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
4726
4727 if (join != NULL) {
4728 current_block()->Goto(join, NULL, false);
4729 } else {
4730 return ast_context()->ReturnValue(Pop());
4731 }
4732 }
4733
4734 ASSERT(join != NULL);
4735 set_current_block(join);
4736 return ast_context()->ReturnValue(Pop());
4633 } 4737 }
4634 4738
4635 4739
4636 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( 4740 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
4637 int position, 4741 int position,
4638 BailoutId assignment_id, 4742 BailoutId assignment_id,
4639 HValue* object, 4743 HValue* object,
4640 HValue* store_value, 4744 HValue* store_value,
4641 HValue* result_value, 4745 HValue* result_value,
4642 SmallMapList* types, 4746 SmallMapList* types,
(...skipping 5086 matching lines...) Expand 10 before | Expand all | Expand 10 after
9729 if (ShouldProduceTraceOutput()) { 9833 if (ShouldProduceTraceOutput()) {
9730 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9834 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9731 } 9835 }
9732 9836
9733 #ifdef DEBUG 9837 #ifdef DEBUG
9734 graph_->Verify(false); // No full verify. 9838 graph_->Verify(false); // No full verify.
9735 #endif 9839 #endif
9736 } 9840 }
9737 9841
9738 } } // namespace v8::internal 9842 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698