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 5197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5208 CHECK_ALIVE(VisitForValue(expr->value())); | 5208 CHECK_ALIVE(VisitForValue(expr->value())); |
5209 HValue* value = environment()->ExpressionStackAt(0); | 5209 HValue* value = environment()->ExpressionStackAt(0); |
5210 HValue* object = environment()->ExpressionStackAt(1); | 5210 HValue* object = environment()->ExpressionStackAt(1); |
5211 | 5211 |
5212 Literal* key = prop->key()->AsLiteral(); | 5212 Literal* key = prop->key()->AsLiteral(); |
5213 Handle<String> name = Handle<String>::cast(key->handle()); | 5213 Handle<String> name = Handle<String>::cast(key->handle()); |
5214 ASSERT(!name.is_null()); | 5214 ASSERT(!name.is_null()); |
5215 | 5215 |
5216 HInstruction* instr = NULL; | 5216 HInstruction* instr = NULL; |
5217 SmallMapList* types = expr->GetReceiverTypes(); | 5217 SmallMapList* types = expr->GetReceiverTypes(); |
5218 if (expr->IsMonomorphic()) { | 5218 bool monomorphic = expr->IsMonomorphic(); |
5219 Handle<Map> map = types->first(); | 5219 Handle<Map> map; |
| 5220 if (monomorphic) { |
| 5221 map = types->first(); |
| 5222 if (map->is_dictionary_map()) monomorphic = false; |
| 5223 } |
| 5224 if (monomorphic) { |
5220 Handle<AccessorPair> accessors; | 5225 Handle<AccessorPair> accessors; |
5221 Handle<JSObject> holder; | 5226 Handle<JSObject> holder; |
5222 if (LookupAccessorPair(map, name, &accessors, &holder)) { | 5227 if (LookupAccessorPair(map, name, &accessors, &holder)) { |
5223 Drop(2); | 5228 Drop(2); |
5224 instr = BuildCallSetter(object, value, map, accessors, holder); | 5229 instr = BuildCallSetter(object, value, map, accessors, holder); |
5225 } else { | 5230 } else { |
5226 Drop(2); | 5231 Drop(2); |
5227 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, | 5232 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, |
5228 name, | 5233 name, |
5229 value, | 5234 value, |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5385 prop->RecordTypeFeedback(oracle(), zone()); | 5390 prop->RecordTypeFeedback(oracle(), zone()); |
5386 | 5391 |
5387 if (prop->key()->IsPropertyName()) { | 5392 if (prop->key()->IsPropertyName()) { |
5388 // Named property. | 5393 // Named property. |
5389 CHECK_ALIVE(VisitForValue(prop->obj())); | 5394 CHECK_ALIVE(VisitForValue(prop->obj())); |
5390 HValue* object = Top(); | 5395 HValue* object = Top(); |
5391 | 5396 |
5392 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 5397 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
5393 Handle<Map> map; | 5398 Handle<Map> map; |
5394 HInstruction* load; | 5399 HInstruction* load; |
5395 if (prop->IsMonomorphic()) { | 5400 bool monomorphic = prop->IsMonomorphic(); |
| 5401 if (monomorphic) { |
5396 map = prop->GetReceiverTypes()->first(); | 5402 map = prop->GetReceiverTypes()->first(); |
| 5403 // We can't generate code for a monomorphic dict mode load so |
| 5404 // just pretend it is not monomorphic. |
| 5405 if (map->is_dictionary_map()) monomorphic = false; |
| 5406 } |
| 5407 if (monomorphic) { |
5397 Handle<AccessorPair> accessors; | 5408 Handle<AccessorPair> accessors; |
5398 Handle<JSObject> holder; | 5409 Handle<JSObject> holder; |
5399 if (LookupAccessorPair(map, name, &accessors, &holder)) { | 5410 if (LookupAccessorPair(map, name, &accessors, &holder)) { |
5400 load = BuildCallGetter(object, map, accessors, holder); | 5411 load = BuildCallGetter(object, map, accessors, holder); |
5401 } else { | 5412 } else { |
5402 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 5413 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
5403 } | 5414 } |
5404 } else { | 5415 } else { |
5405 load = BuildLoadNamedGeneric(object, name, prop); | 5416 load = BuildLoadNamedGeneric(object, name, prop); |
5406 } | 5417 } |
5407 PushAndAdd(load); | 5418 PushAndAdd(load); |
5408 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); | 5419 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); |
5409 | 5420 |
5410 CHECK_ALIVE(VisitForValue(expr->value())); | 5421 CHECK_ALIVE(VisitForValue(expr->value())); |
5411 HValue* right = Pop(); | 5422 HValue* right = Pop(); |
5412 HValue* left = Pop(); | 5423 HValue* left = Pop(); |
5413 | 5424 |
5414 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5425 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
5415 PushAndAdd(instr); | 5426 PushAndAdd(instr); |
5416 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 5427 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
5417 | 5428 |
5418 HInstruction* store; | 5429 HInstruction* store; |
5419 if (map.is_null()) { | 5430 if (!monomorphic) { |
5420 // If we don't know the monomorphic type, do a generic store. | 5431 // If we don't know the monomorphic type, do a generic store. |
5421 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr)); | 5432 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr)); |
5422 } else { | 5433 } else { |
5423 Handle<AccessorPair> accessors; | 5434 Handle<AccessorPair> accessors; |
5424 Handle<JSObject> holder; | 5435 Handle<JSObject> holder; |
5425 // Because we re-use the load type feedback, there might be no setter. | 5436 // Because we re-use the load type feedback, there might be no setter. |
5426 if (LookupAccessorPair(map, name, &accessors, &holder) && | 5437 if (LookupAccessorPair(map, name, &accessors, &holder) && |
5427 accessors->setter()->IsJSFunction()) { | 5438 accessors->setter()->IsJSFunction()) { |
5428 store = BuildCallSetter(object, instr, map, accessors, holder); | 5439 store = BuildCallSetter(object, instr, map, accessors, holder); |
5429 } else { | 5440 } else { |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5710 // We haven't found a JavaScript accessor anywhere. | 5721 // We haven't found a JavaScript accessor anywhere. |
5711 return false; | 5722 return false; |
5712 } | 5723 } |
5713 | 5724 |
5714 | 5725 |
5715 HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object, | 5726 HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object, |
5716 Handle<String> name, | 5727 Handle<String> name, |
5717 Property* expr, | 5728 Property* expr, |
5718 Handle<Map> map) { | 5729 Handle<Map> map) { |
5719 // Handle a load from a known field. | 5730 // Handle a load from a known field. |
| 5731 ASSERT(!map->is_dictionary_map()); |
5720 LookupResult lookup(isolate()); | 5732 LookupResult lookup(isolate()); |
5721 map->LookupDescriptor(NULL, *name, &lookup); | 5733 map->LookupDescriptor(NULL, *name, &lookup); |
5722 if (lookup.IsField()) { | 5734 if (lookup.IsField()) { |
5723 return BuildLoadNamedField(object, map, &lookup, true); | 5735 return BuildLoadNamedField(object, map, &lookup, true); |
5724 } | 5736 } |
5725 | 5737 |
5726 // Handle a load of a constant known function. | 5738 // Handle a load of a constant known function. |
5727 if (lookup.IsConstantFunction()) { | 5739 if (lookup.IsConstantFunction()) { |
5728 AddInstruction(new(zone()) HCheckNonSmi(object)); | 5740 AddInstruction(new(zone()) HCheckNonSmi(object)); |
5729 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); | 5741 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6343 | 6355 |
6344 } else if (expr->IsFunctionPrototype()) { | 6356 } else if (expr->IsFunctionPrototype()) { |
6345 HValue* function = Pop(); | 6357 HValue* function = Pop(); |
6346 AddInstruction(new(zone()) HCheckNonSmi(function)); | 6358 AddInstruction(new(zone()) HCheckNonSmi(function)); |
6347 instr = new(zone()) HLoadFunctionPrototype(function); | 6359 instr = new(zone()) HLoadFunctionPrototype(function); |
6348 | 6360 |
6349 } else if (expr->key()->IsPropertyName()) { | 6361 } else if (expr->key()->IsPropertyName()) { |
6350 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 6362 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
6351 SmallMapList* types = expr->GetReceiverTypes(); | 6363 SmallMapList* types = expr->GetReceiverTypes(); |
6352 | 6364 |
| 6365 bool monomorphic = expr->IsMonomorphic(); |
| 6366 Handle<Map> map; |
6353 if (expr->IsMonomorphic()) { | 6367 if (expr->IsMonomorphic()) { |
6354 Handle<Map> map = types->first(); | 6368 map = types->first(); |
| 6369 if (map->is_dictionary_map()) monomorphic = false; |
| 6370 } |
| 6371 if (monomorphic) { |
6355 Handle<AccessorPair> accessors; | 6372 Handle<AccessorPair> accessors; |
6356 Handle<JSObject> holder; | 6373 Handle<JSObject> holder; |
6357 if (LookupAccessorPair(map, name, &accessors, &holder)) { | 6374 if (LookupAccessorPair(map, name, &accessors, &holder)) { |
6358 AddCheckConstantFunction(holder, Top(), map, true); | 6375 AddCheckConstantFunction(holder, Top(), map, true); |
6359 Handle<JSFunction> getter(JSFunction::cast(accessors->getter())); | 6376 Handle<JSFunction> getter(JSFunction::cast(accessors->getter())); |
6360 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; | 6377 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; |
6361 AddInstruction(new(zone()) HPushArgument(Pop())); | 6378 AddInstruction(new(zone()) HPushArgument(Pop())); |
6362 instr = new(zone()) HCallConstantFunction(getter, 1); | 6379 instr = new(zone()) HCallConstantFunction(getter, 1); |
6363 } else { | 6380 } else { |
6364 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); | 6381 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); |
(...skipping 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7853 if (prop->key()->IsPropertyName()) { | 7870 if (prop->key()->IsPropertyName()) { |
7854 // Named property. | 7871 // Named property. |
7855 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 7872 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
7856 | 7873 |
7857 CHECK_ALIVE(VisitForValue(prop->obj())); | 7874 CHECK_ALIVE(VisitForValue(prop->obj())); |
7858 HValue* object = Top(); | 7875 HValue* object = Top(); |
7859 | 7876 |
7860 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 7877 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
7861 Handle<Map> map; | 7878 Handle<Map> map; |
7862 HInstruction* load; | 7879 HInstruction* load; |
7863 if (prop->IsMonomorphic()) { | 7880 bool monomorphic = prop->IsMonomorphic(); |
| 7881 if (monomorphic) { |
7864 map = prop->GetReceiverTypes()->first(); | 7882 map = prop->GetReceiverTypes()->first(); |
| 7883 if (map->is_dictionary_map()) monomorphic = false; |
| 7884 } |
| 7885 if (monomorphic) { |
7865 Handle<AccessorPair> accessors; | 7886 Handle<AccessorPair> accessors; |
7866 Handle<JSObject> holder; | 7887 Handle<JSObject> holder; |
7867 if (LookupAccessorPair(map, name, &accessors, &holder)) { | 7888 if (LookupAccessorPair(map, name, &accessors, &holder)) { |
7868 load = BuildCallGetter(object, map, accessors, holder); | 7889 load = BuildCallGetter(object, map, accessors, holder); |
7869 } else { | 7890 } else { |
7870 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 7891 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
7871 } | 7892 } |
7872 } else { | 7893 } else { |
7873 load = BuildLoadNamedGeneric(object, name, prop); | 7894 load = BuildLoadNamedGeneric(object, name, prop); |
7874 } | 7895 } |
7875 PushAndAdd(load); | 7896 PushAndAdd(load); |
7876 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); | 7897 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); |
7877 | 7898 |
7878 after = BuildIncrement(returns_original_input, expr); | 7899 after = BuildIncrement(returns_original_input, expr); |
7879 input = Pop(); | 7900 input = Pop(); |
7880 | 7901 |
7881 HInstruction* store; | 7902 HInstruction* store; |
7882 if (map.is_null()) { | 7903 if (!monomorphic) { |
7883 // If we don't know the monomorphic type, do a generic store. | 7904 // If we don't know the monomorphic type, do a generic store. |
7884 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); | 7905 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); |
7885 } else { | 7906 } else { |
7886 Handle<AccessorPair> accessors; | 7907 Handle<AccessorPair> accessors; |
7887 Handle<JSObject> holder; | 7908 Handle<JSObject> holder; |
7888 // Because we re-use the load type feedback, there might be no setter. | 7909 // Because we re-use the load type feedback, there might be no setter. |
7889 if (LookupAccessorPair(map, name, &accessors, &holder) && | 7910 if (LookupAccessorPair(map, name, &accessors, &holder) && |
7890 accessors->setter()->IsJSFunction()) { | 7911 accessors->setter()->IsJSFunction()) { |
7891 store = BuildCallSetter(object, after, map, accessors, holder); | 7912 store = BuildCallSetter(object, after, map, accessors, holder); |
7892 } else { | 7913 } else { |
(...skipping 1771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9664 } | 9685 } |
9665 } | 9686 } |
9666 | 9687 |
9667 #ifdef DEBUG | 9688 #ifdef DEBUG |
9668 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9689 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9669 if (allocator_ != NULL) allocator_->Verify(); | 9690 if (allocator_ != NULL) allocator_->Verify(); |
9670 #endif | 9691 #endif |
9671 } | 9692 } |
9672 | 9693 |
9673 } } // namespace v8::internal | 9694 } } // namespace v8::internal |
OLD | NEW |