| 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 |