Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 4644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4655 | 4655 |
| 4656 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, | 4656 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, |
| 4657 literals, | 4657 literals, |
| 4658 expr->pattern(), | 4658 expr->pattern(), |
| 4659 expr->flags(), | 4659 expr->flags(), |
| 4660 expr->literal_index()); | 4660 expr->literal_index()); |
| 4661 return ast_context()->ReturnInstruction(instr, expr->id()); | 4661 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 4662 } | 4662 } |
| 4663 | 4663 |
| 4664 | 4664 |
| 4665 static void LookupInPrototypes(Handle<Map> map, | |
| 4666 Handle<String> name, | |
| 4667 LookupResult* lookup) { | |
| 4668 while (map->prototype()->IsJSObject()) { | |
| 4669 Handle<JSObject> holder(JSObject::cast(map->prototype())); | |
| 4670 if (!holder->HasFastProperties()) break; | |
| 4671 map = Handle<Map>(holder->map()); | |
| 4672 map->LookupDescriptor(*holder, *name, lookup); | |
| 4673 if (lookup->IsFound()) return; | |
| 4674 } | |
| 4675 lookup->NotFound(); | |
| 4676 } | |
| 4677 | |
| 4678 | |
| 4679 // Tries to find a JavaScript accessor of the given name in the prototype chain | |
| 4680 // starting at the given map. Return true iff there is one, including the | |
| 4681 // corresponding AccessorPair plus its holder (which could be null when the | |
| 4682 // accessor is found directly in the given map). | |
| 4683 static bool LookupAccessorPair(Handle<Map> map, | |
| 4684 Handle<String> name, | |
| 4685 Handle<AccessorPair>* accessors, | |
| 4686 Handle<JSObject>* holder) { | |
| 4687 LookupResult lookup(map->GetIsolate()); | |
| 4688 | |
| 4689 // Check for a JavaScript accessor directly in the map. | |
| 4690 map->LookupDescriptor(NULL, *name, &lookup); | |
| 4691 if (lookup.IsPropertyCallbacks()) { | |
| 4692 Handle<Object> callback(lookup.GetValueFromMap(*map)); | |
| 4693 if (!callback->IsAccessorPair()) return false; | |
| 4694 *accessors = Handle<AccessorPair>::cast(callback); | |
| 4695 *holder = Handle<JSObject>(); | |
| 4696 return true; | |
| 4697 } | |
| 4698 | |
| 4699 // Everything else, e.g. a field, can't be an accessor call. | |
| 4700 if (lookup.IsFound()) return false; | |
| 4701 | |
| 4702 // Check for a JavaScript accessor somewhere in the proto chain. | |
| 4703 LookupInPrototypes(map, name, &lookup); | |
| 4704 if (lookup.IsPropertyCallbacks()) { | |
| 4705 Handle<Object> callback(lookup.GetValue()); | |
| 4706 if (!callback->IsAccessorPair()) return false; | |
| 4707 *accessors = Handle<AccessorPair>::cast(callback); | |
| 4708 *holder = Handle<JSObject>(lookup.holder()); | |
| 4709 return true; | |
| 4710 } | |
| 4711 | |
| 4712 // We haven't found a JavaScript accessor anywhere. | |
| 4713 return false; | |
| 4714 } | |
| 4715 | |
| 4716 | |
| 4717 static bool LookupGetter(Handle<Map> map, | |
| 4718 Handle<String> name, | |
| 4719 Handle<JSFunction>* getter, | |
| 4720 Handle<JSObject>* holder) { | |
| 4721 Handle<AccessorPair> accessors; | |
| 4722 if (LookupAccessorPair(map, name, &accessors, holder) && | |
| 4723 (*accessors)->getter()->IsJSFunction()) { | |
|
Michael Starzinger
2012/08/16 09:55:58
No need to do open the handle here, that will be d
Sven Panne
2012/08/16 10:47:40
Done.
| |
| 4724 *getter = Handle<JSFunction>(JSFunction::cast((*accessors)->getter())); | |
|
Michael Starzinger
2012/08/16 09:55:58
Likewise.
Sven Panne
2012/08/16 10:47:40
Done.
| |
| 4725 return true; | |
| 4726 } | |
| 4727 return false; | |
| 4728 } | |
| 4729 | |
| 4730 | |
| 4731 static bool LookupSetter(Handle<Map> map, | |
| 4732 Handle<String> name, | |
| 4733 Handle<JSFunction>* setter, | |
| 4734 Handle<JSObject>* holder) { | |
| 4735 Handle<AccessorPair> accessors; | |
| 4736 if (LookupAccessorPair(map, name, &accessors, holder) && | |
| 4737 (*accessors)->setter()->IsJSFunction()) { | |
|
Michael Starzinger
2012/08/16 09:55:58
Likewise.
Sven Panne
2012/08/16 10:47:40
Done.
| |
| 4738 *setter = Handle<JSFunction>(JSFunction::cast((*accessors)->setter())); | |
|
Michael Starzinger
2012/08/16 09:55:58
Likewise.
Sven Panne
2012/08/16 10:47:40
Done.
| |
| 4739 return true; | |
| 4740 } | |
| 4741 return false; | |
| 4742 } | |
| 4743 | |
| 4744 | |
| 4665 // Determines whether the given array or object literal boilerplate satisfies | 4745 // Determines whether the given array or object literal boilerplate satisfies |
| 4666 // all limits to be considered for fast deep-copying and computes the total | 4746 // all limits to be considered for fast deep-copying and computes the total |
| 4667 // size of all objects that are part of the graph. | 4747 // size of all objects that are part of the graph. |
| 4668 static bool IsFastLiteral(Handle<JSObject> boilerplate, | 4748 static bool IsFastLiteral(Handle<JSObject> boilerplate, |
| 4669 int max_depth, | 4749 int max_depth, |
| 4670 int* max_properties, | 4750 int* max_properties, |
| 4671 int* total_size) { | 4751 int* total_size) { |
| 4672 ASSERT(max_depth >= 0 && *max_properties >= 0); | 4752 ASSERT(max_depth >= 0 && *max_properties >= 0); |
| 4673 if (max_depth == 0) return false; | 4753 if (max_depth == 0) return false; |
| 4674 | 4754 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4780 CHECK_ALIVE(VisitForValue(value)); | 4860 CHECK_ALIVE(VisitForValue(value)); |
| 4781 HValue* value = Pop(); | 4861 HValue* value = Pop(); |
| 4782 Handle<Map> map = property->GetReceiverType(); | 4862 Handle<Map> map = property->GetReceiverType(); |
| 4783 Handle<String> name = property->key()->AsPropertyName(); | 4863 Handle<String> name = property->key()->AsPropertyName(); |
| 4784 HInstruction* store; | 4864 HInstruction* store; |
| 4785 if (map.is_null()) { | 4865 if (map.is_null()) { |
| 4786 // If we don't know the monomorphic type, do a generic store. | 4866 // If we don't know the monomorphic type, do a generic store. |
| 4787 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); | 4867 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); |
| 4788 } else { | 4868 } else { |
| 4789 #if DEBUG | 4869 #if DEBUG |
| 4790 Handle<AccessorPair> accessors; | 4870 Handle<JSFunction> setter; |
| 4791 Handle<JSObject> holder; | 4871 Handle<JSObject> holder; |
| 4792 ASSERT(!LookupAccessorPair(map, name, &accessors, &holder)); | 4872 ASSERT(!LookupSetter(map, name, &setter, &holder)); |
| 4793 #endif | 4873 #endif |
| 4794 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, | 4874 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, |
| 4795 name, | 4875 name, |
| 4796 value, | 4876 value, |
| 4797 map)); | 4877 map)); |
| 4798 } | 4878 } |
| 4799 AddInstruction(store); | 4879 AddInstruction(store); |
| 4800 if (store->HasObservableSideEffects()) AddSimulate(key->id()); | 4880 if (store->HasObservableSideEffects()) AddSimulate(key->id()); |
| 4801 } else { | 4881 } else { |
| 4802 CHECK_ALIVE(VisitForEffect(value)); | 4882 CHECK_ALIVE(VisitForEffect(value)); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5031 HValue* context = environment()->LookupContext(); | 5111 HValue* context = environment()->LookupContext(); |
| 5032 return new(zone()) HStoreNamedGeneric( | 5112 return new(zone()) HStoreNamedGeneric( |
| 5033 context, | 5113 context, |
| 5034 object, | 5114 object, |
| 5035 name, | 5115 name, |
| 5036 value, | 5116 value, |
| 5037 function_strict_mode_flag()); | 5117 function_strict_mode_flag()); |
| 5038 } | 5118 } |
| 5039 | 5119 |
| 5040 | 5120 |
| 5041 static void LookupInPrototypes(Handle<Map> map, | |
| 5042 Handle<String> name, | |
| 5043 LookupResult* lookup) { | |
| 5044 while (map->prototype()->IsJSObject()) { | |
| 5045 Handle<JSObject> holder(JSObject::cast(map->prototype())); | |
| 5046 if (!holder->HasFastProperties()) break; | |
| 5047 map = Handle<Map>(holder->map()); | |
| 5048 map->LookupDescriptor(*holder, *name, lookup); | |
| 5049 if (lookup->IsFound()) return; | |
| 5050 } | |
| 5051 lookup->NotFound(); | |
| 5052 } | |
| 5053 | |
| 5054 | |
| 5055 HInstruction* HGraphBuilder::BuildCallSetter(HValue* object, | 5121 HInstruction* HGraphBuilder::BuildCallSetter(HValue* object, |
| 5056 HValue* value, | 5122 HValue* value, |
| 5057 Handle<Map> map, | 5123 Handle<Map> map, |
| 5058 Handle<AccessorPair> accessors, | 5124 Handle<JSFunction> setter, |
| 5059 Handle<JSObject> holder) { | 5125 Handle<JSObject> holder) { |
| 5060 Handle<JSFunction> setter(JSFunction::cast(accessors->setter())); | |
| 5061 AddCheckConstantFunction(holder, object, map, true); | 5126 AddCheckConstantFunction(holder, object, map, true); |
| 5062 AddInstruction(new(zone()) HPushArgument(object)); | 5127 AddInstruction(new(zone()) HPushArgument(object)); |
| 5063 AddInstruction(new(zone()) HPushArgument(value)); | 5128 AddInstruction(new(zone()) HPushArgument(value)); |
| 5064 return new(zone()) HCallConstantFunction(setter, 2); | 5129 return new(zone()) HCallConstantFunction(setter, 2); |
| 5065 } | 5130 } |
| 5066 | 5131 |
| 5067 | 5132 |
| 5068 HInstruction* HGraphBuilder::BuildStoreNamedMonomorphic(HValue* object, | 5133 HInstruction* HGraphBuilder::BuildStoreNamedMonomorphic(HValue* object, |
| 5069 Handle<String> name, | 5134 Handle<String> name, |
| 5070 HValue* value, | 5135 HValue* value, |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5230 | 5295 |
| 5231 HInstruction* instr = NULL; | 5296 HInstruction* instr = NULL; |
| 5232 SmallMapList* types = expr->GetReceiverTypes(); | 5297 SmallMapList* types = expr->GetReceiverTypes(); |
| 5233 bool monomorphic = expr->IsMonomorphic(); | 5298 bool monomorphic = expr->IsMonomorphic(); |
| 5234 Handle<Map> map; | 5299 Handle<Map> map; |
| 5235 if (monomorphic) { | 5300 if (monomorphic) { |
| 5236 map = types->first(); | 5301 map = types->first(); |
| 5237 if (map->is_dictionary_map()) monomorphic = false; | 5302 if (map->is_dictionary_map()) monomorphic = false; |
| 5238 } | 5303 } |
| 5239 if (monomorphic) { | 5304 if (monomorphic) { |
| 5240 Handle<AccessorPair> accessors; | 5305 Handle<JSFunction> setter; |
| 5241 Handle<JSObject> holder; | 5306 Handle<JSObject> holder; |
| 5242 if (LookupAccessorPair(map, name, &accessors, &holder)) { | 5307 if (LookupSetter(map, name, &setter, &holder)) { |
| 5243 Handle<JSFunction> setter(JSFunction::cast(accessors->setter())); | |
| 5244 AddCheckConstantFunction(holder, object, map, true); | 5308 AddCheckConstantFunction(holder, object, map, true); |
| 5245 if (FLAG_inline_accessors && TryInlineSetter(setter, expr, value)) { | 5309 if (FLAG_inline_accessors && TryInlineSetter(setter, expr, value)) { |
| 5246 return; | 5310 return; |
| 5247 } | 5311 } |
| 5248 Drop(2); | 5312 Drop(2); |
| 5249 AddInstruction(new(zone()) HPushArgument(object)); | 5313 AddInstruction(new(zone()) HPushArgument(object)); |
| 5250 AddInstruction(new(zone()) HPushArgument(value)); | 5314 AddInstruction(new(zone()) HPushArgument(value)); |
| 5251 instr = new(zone()) HCallConstantFunction(setter, 2); | 5315 instr = new(zone()) HCallConstantFunction(setter, 2); |
| 5252 } else { | 5316 } else { |
| 5253 Drop(2); | 5317 Drop(2); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5420 Handle<Map> map; | 5484 Handle<Map> map; |
| 5421 HInstruction* load; | 5485 HInstruction* load; |
| 5422 bool monomorphic = prop->IsMonomorphic(); | 5486 bool monomorphic = prop->IsMonomorphic(); |
| 5423 if (monomorphic) { | 5487 if (monomorphic) { |
| 5424 map = prop->GetReceiverTypes()->first(); | 5488 map = prop->GetReceiverTypes()->first(); |
| 5425 // We can't generate code for a monomorphic dict mode load so | 5489 // We can't generate code for a monomorphic dict mode load so |
| 5426 // just pretend it is not monomorphic. | 5490 // just pretend it is not monomorphic. |
| 5427 if (map->is_dictionary_map()) monomorphic = false; | 5491 if (map->is_dictionary_map()) monomorphic = false; |
| 5428 } | 5492 } |
| 5429 if (monomorphic) { | 5493 if (monomorphic) { |
| 5430 Handle<AccessorPair> accessors; | 5494 Handle<JSFunction> getter; |
| 5431 Handle<JSObject> holder; | 5495 Handle<JSObject> holder; |
| 5432 if (LookupAccessorPair(map, name, &accessors, &holder)) { | 5496 if (LookupGetter(map, name, &getter, &holder)) { |
| 5433 load = BuildCallGetter(object, map, accessors, holder); | 5497 load = BuildCallGetter(object, map, getter, holder); |
| 5434 } else { | 5498 } else { |
| 5435 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 5499 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
| 5436 } | 5500 } |
| 5437 } else { | 5501 } else { |
| 5438 load = BuildLoadNamedGeneric(object, name, prop); | 5502 load = BuildLoadNamedGeneric(object, name, prop); |
| 5439 } | 5503 } |
| 5440 PushAndAdd(load); | 5504 PushAndAdd(load); |
| 5441 if (load->HasObservableSideEffects()) AddSimulate(prop->LoadId()); | 5505 if (load->HasObservableSideEffects()) AddSimulate(prop->LoadId()); |
| 5442 | 5506 |
| 5443 CHECK_ALIVE(VisitForValue(expr->value())); | 5507 CHECK_ALIVE(VisitForValue(expr->value())); |
| 5444 HValue* right = Pop(); | 5508 HValue* right = Pop(); |
| 5445 HValue* left = Pop(); | 5509 HValue* left = Pop(); |
| 5446 | 5510 |
| 5447 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5511 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 5448 PushAndAdd(instr); | 5512 PushAndAdd(instr); |
| 5449 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 5513 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| 5450 | 5514 |
| 5451 HInstruction* store; | 5515 HInstruction* store; |
| 5452 if (!monomorphic) { | 5516 if (!monomorphic) { |
| 5453 // If we don't know the monomorphic type, do a generic store. | 5517 // If we don't know the monomorphic type, do a generic store. |
| 5454 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr)); | 5518 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr)); |
| 5455 } else { | 5519 } else { |
| 5456 Handle<AccessorPair> accessors; | 5520 Handle<JSFunction> setter; |
| 5457 Handle<JSObject> holder; | 5521 Handle<JSObject> holder; |
| 5458 // Because we re-use the load type feedback, there might be no setter. | 5522 // Because we re-use the load type feedback, there might be no setter. |
| 5459 if (LookupAccessorPair(map, name, &accessors, &holder) && | 5523 if (LookupSetter(map, name, &setter, &holder)) { |
| 5460 accessors->setter()->IsJSFunction()) { | 5524 store = BuildCallSetter(object, instr, map, setter, holder); |
| 5461 store = BuildCallSetter(object, instr, map, accessors, holder); | |
| 5462 } else { | 5525 } else { |
| 5463 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, | 5526 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, |
| 5464 name, | 5527 name, |
| 5465 instr, | 5528 instr, |
| 5466 map)); | 5529 map)); |
| 5467 } | 5530 } |
| 5468 } | 5531 } |
| 5469 AddInstruction(store); | 5532 AddInstruction(store); |
| 5470 // Drop the simulated receiver and value. Return the value. | 5533 // Drop the simulated receiver and value. Return the value. |
| 5471 Drop(2); | 5534 Drop(2); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5695 AddInstruction(new(zone()) HSoftDeoptimize); | 5758 AddInstruction(new(zone()) HSoftDeoptimize); |
| 5696 current_block()->MarkAsDeoptimizing(); | 5759 current_block()->MarkAsDeoptimizing(); |
| 5697 } | 5760 } |
| 5698 HValue* context = environment()->LookupContext(); | 5761 HValue* context = environment()->LookupContext(); |
| 5699 return new(zone()) HLoadNamedGeneric(context, object, name); | 5762 return new(zone()) HLoadNamedGeneric(context, object, name); |
| 5700 } | 5763 } |
| 5701 | 5764 |
| 5702 | 5765 |
| 5703 HInstruction* HGraphBuilder::BuildCallGetter(HValue* object, | 5766 HInstruction* HGraphBuilder::BuildCallGetter(HValue* object, |
| 5704 Handle<Map> map, | 5767 Handle<Map> map, |
| 5705 Handle<AccessorPair> accessors, | 5768 Handle<JSFunction> getter, |
| 5706 Handle<JSObject> holder) { | 5769 Handle<JSObject> holder) { |
| 5707 Handle<JSFunction> getter(JSFunction::cast(accessors->getter())); | |
| 5708 AddCheckConstantFunction(holder, object, map, true); | 5770 AddCheckConstantFunction(holder, object, map, true); |
| 5709 AddInstruction(new(zone()) HPushArgument(object)); | 5771 AddInstruction(new(zone()) HPushArgument(object)); |
| 5710 return new(zone()) HCallConstantFunction(getter, 1); | 5772 return new(zone()) HCallConstantFunction(getter, 1); |
| 5711 } | 5773 } |
| 5712 | 5774 |
| 5713 | 5775 |
| 5714 bool HGraphBuilder::LookupAccessorPair(Handle<Map> map, | |
| 5715 Handle<String> name, | |
| 5716 Handle<AccessorPair>* accessors, | |
| 5717 Handle<JSObject>* holder) { | |
| 5718 LookupResult lookup(isolate()); | |
| 5719 | |
| 5720 // Check for a JavaScript accessor directly in the map. | |
| 5721 map->LookupDescriptor(NULL, *name, &lookup); | |
| 5722 if (lookup.IsPropertyCallbacks()) { | |
| 5723 Handle<Object> callback(lookup.GetValueFromMap(*map)); | |
| 5724 if (!callback->IsAccessorPair()) return false; | |
| 5725 *accessors = Handle<AccessorPair>::cast(callback); | |
| 5726 *holder = Handle<JSObject>(); | |
| 5727 return true; | |
| 5728 } | |
| 5729 | |
| 5730 // Everything else, e.g. a field, can't be an accessor call. | |
| 5731 if (lookup.IsFound()) return false; | |
| 5732 | |
| 5733 // Check for a JavaScript accessor somewhere in the proto chain. | |
| 5734 LookupInPrototypes(map, name, &lookup); | |
| 5735 if (lookup.IsPropertyCallbacks()) { | |
| 5736 Handle<Object> callback(lookup.GetValue()); | |
| 5737 if (!callback->IsAccessorPair()) return false; | |
| 5738 *accessors = Handle<AccessorPair>::cast(callback); | |
| 5739 *holder = Handle<JSObject>(lookup.holder()); | |
| 5740 return true; | |
| 5741 } | |
| 5742 | |
| 5743 // We haven't found a JavaScript accessor anywhere. | |
| 5744 return false; | |
| 5745 } | |
| 5746 | |
| 5747 | |
| 5748 HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object, | 5776 HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object, |
| 5749 Handle<String> name, | 5777 Handle<String> name, |
| 5750 Property* expr, | 5778 Property* expr, |
| 5751 Handle<Map> map) { | 5779 Handle<Map> map) { |
| 5752 // Handle a load from a known field. | 5780 // Handle a load from a known field. |
| 5753 ASSERT(!map->is_dictionary_map()); | 5781 ASSERT(!map->is_dictionary_map()); |
| 5754 LookupResult lookup(isolate()); | 5782 LookupResult lookup(isolate()); |
| 5755 map->LookupDescriptor(NULL, *name, &lookup); | 5783 map->LookupDescriptor(NULL, *name, &lookup); |
| 5756 if (lookup.IsField()) { | 5784 if (lookup.IsField()) { |
| 5757 return BuildLoadNamedField(object, map, &lookup, true); | 5785 return BuildLoadNamedField(object, map, &lookup, true); |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6384 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 6412 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 6385 SmallMapList* types = expr->GetReceiverTypes(); | 6413 SmallMapList* types = expr->GetReceiverTypes(); |
| 6386 | 6414 |
| 6387 bool monomorphic = expr->IsMonomorphic(); | 6415 bool monomorphic = expr->IsMonomorphic(); |
| 6388 Handle<Map> map; | 6416 Handle<Map> map; |
| 6389 if (expr->IsMonomorphic()) { | 6417 if (expr->IsMonomorphic()) { |
| 6390 map = types->first(); | 6418 map = types->first(); |
| 6391 if (map->is_dictionary_map()) monomorphic = false; | 6419 if (map->is_dictionary_map()) monomorphic = false; |
| 6392 } | 6420 } |
| 6393 if (monomorphic) { | 6421 if (monomorphic) { |
| 6394 Handle<AccessorPair> accessors; | 6422 Handle<JSFunction> getter; |
| 6395 Handle<JSObject> holder; | 6423 Handle<JSObject> holder; |
| 6396 if (LookupAccessorPair(map, name, &accessors, &holder)) { | 6424 if (LookupGetter(map, name, &getter, &holder)) { |
| 6397 AddCheckConstantFunction(holder, Top(), map, true); | 6425 AddCheckConstantFunction(holder, Top(), map, true); |
| 6398 Handle<JSFunction> getter(JSFunction::cast(accessors->getter())); | |
| 6399 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; | 6426 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; |
| 6400 AddInstruction(new(zone()) HPushArgument(Pop())); | 6427 AddInstruction(new(zone()) HPushArgument(Pop())); |
| 6401 instr = new(zone()) HCallConstantFunction(getter, 1); | 6428 instr = new(zone()) HCallConstantFunction(getter, 1); |
| 6402 } else { | 6429 } else { |
| 6403 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); | 6430 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); |
| 6404 } | 6431 } |
| 6405 } else if (types != NULL && types->length() > 1) { | 6432 } else if (types != NULL && types->length() > 1) { |
| 6406 return HandlePolymorphicLoadNamedField(expr, Pop(), types, name); | 6433 return HandlePolymorphicLoadNamedField(expr, Pop(), types, name); |
| 6407 } else { | 6434 } else { |
| 6408 instr = BuildLoadNamedGeneric(Pop(), name, expr); | 6435 instr = BuildLoadNamedGeneric(Pop(), name, expr); |
| (...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7860 | 7887 |
| 7861 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 7888 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 7862 Handle<Map> map; | 7889 Handle<Map> map; |
| 7863 HInstruction* load; | 7890 HInstruction* load; |
| 7864 bool monomorphic = prop->IsMonomorphic(); | 7891 bool monomorphic = prop->IsMonomorphic(); |
| 7865 if (monomorphic) { | 7892 if (monomorphic) { |
| 7866 map = prop->GetReceiverTypes()->first(); | 7893 map = prop->GetReceiverTypes()->first(); |
| 7867 if (map->is_dictionary_map()) monomorphic = false; | 7894 if (map->is_dictionary_map()) monomorphic = false; |
| 7868 } | 7895 } |
| 7869 if (monomorphic) { | 7896 if (monomorphic) { |
| 7870 Handle<AccessorPair> accessors; | 7897 Handle<JSFunction> getter; |
| 7871 Handle<JSObject> holder; | 7898 Handle<JSObject> holder; |
| 7872 if (LookupAccessorPair(map, name, &accessors, &holder)) { | 7899 if (LookupGetter(map, name, &getter, &holder)) { |
| 7873 load = BuildCallGetter(object, map, accessors, holder); | 7900 load = BuildCallGetter(object, map, getter, holder); |
| 7874 } else { | 7901 } else { |
| 7875 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 7902 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
| 7876 } | 7903 } |
| 7877 } else { | 7904 } else { |
| 7878 load = BuildLoadNamedGeneric(object, name, prop); | 7905 load = BuildLoadNamedGeneric(object, name, prop); |
| 7879 } | 7906 } |
| 7880 PushAndAdd(load); | 7907 PushAndAdd(load); |
| 7881 if (load->HasObservableSideEffects()) AddSimulate(prop->LoadId()); | 7908 if (load->HasObservableSideEffects()) AddSimulate(prop->LoadId()); |
| 7882 | 7909 |
| 7883 after = BuildIncrement(returns_original_input, expr); | 7910 after = BuildIncrement(returns_original_input, expr); |
| 7884 input = Pop(); | 7911 input = Pop(); |
| 7885 | 7912 |
| 7886 HInstruction* store; | 7913 HInstruction* store; |
| 7887 if (!monomorphic) { | 7914 if (!monomorphic) { |
| 7888 // If we don't know the monomorphic type, do a generic store. | 7915 // If we don't know the monomorphic type, do a generic store. |
| 7889 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); | 7916 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); |
| 7890 } else { | 7917 } else { |
| 7891 Handle<AccessorPair> accessors; | 7918 Handle<JSFunction> setter; |
| 7892 Handle<JSObject> holder; | 7919 Handle<JSObject> holder; |
| 7893 // Because we re-use the load type feedback, there might be no setter. | 7920 // Because we re-use the load type feedback, there might be no setter. |
|
Michael Starzinger
2012/08/16 09:55:58
We should remove this comment, because there might
Sven Panne
2012/08/16 10:47:40
Done.
| |
| 7894 if (LookupAccessorPair(map, name, &accessors, &holder) && | 7921 if (LookupSetter(map, name, &setter, &holder)) { |
| 7895 accessors->setter()->IsJSFunction()) { | 7922 store = BuildCallSetter(object, after, map, setter, holder); |
| 7896 store = BuildCallSetter(object, after, map, accessors, holder); | |
| 7897 } else { | 7923 } else { |
| 7898 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, | 7924 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, |
| 7899 name, | 7925 name, |
| 7900 after, | 7926 after, |
| 7901 map)); | 7927 map)); |
| 7902 } | 7928 } |
| 7903 } | 7929 } |
| 7904 AddInstruction(store); | 7930 AddInstruction(store); |
| 7905 | 7931 |
| 7906 // Overwrite the receiver in the bailout environment with the result | 7932 // Overwrite the receiver in the bailout environment with the result |
| (...skipping 1766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9673 } | 9699 } |
| 9674 } | 9700 } |
| 9675 | 9701 |
| 9676 #ifdef DEBUG | 9702 #ifdef DEBUG |
| 9677 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9703 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 9678 if (allocator_ != NULL) allocator_->Verify(); | 9704 if (allocator_ != NULL) allocator_->Verify(); |
| 9679 #endif | 9705 #endif |
| 9680 } | 9706 } |
| 9681 | 9707 |
| 9682 } } // namespace v8::internal | 9708 } } // namespace v8::internal |
| OLD | NEW |