| 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 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 529 |
| 530 MaybeObject* LoadIC::Load(Handle<Object> object, | 530 MaybeObject* LoadIC::Load(Handle<Object> object, |
| 531 Handle<String> name) { | 531 Handle<String> name) { |
| 532 // If the object is undefined or null it's illegal to try to get any | 532 // If the object is undefined or null it's illegal to try to get any |
| 533 // of its properties; throw a TypeError in that case. | 533 // of its properties; throw a TypeError in that case. |
| 534 if (object->IsUndefined() || object->IsNull()) { | 534 if (object->IsUndefined() || object->IsNull()) { |
| 535 return TypeError("non_object_property_load", object, name); | 535 return TypeError("non_object_property_load", object, name); |
| 536 } | 536 } |
| 537 | 537 |
| 538 if (FLAG_use_ic) { | 538 if (FLAG_use_ic) { |
| 539 // Use specialized code for getting the length of strings and | |
| 540 // string wrapper objects. The length property of string wrapper | |
| 541 // objects is read-only and therefore always returns the length of | |
| 542 // the underlying string value. See ECMA-262 15.5.5.1. | |
| 543 if (object->IsStringWrapper() && | |
| 544 name->Equals(isolate()->heap()->length_string())) { | |
| 545 Handle<Code> stub; | |
| 546 if (state() == UNINITIALIZED) { | |
| 547 stub = pre_monomorphic_stub(); | |
| 548 } else if (state() == PREMONOMORPHIC || state() == MONOMORPHIC) { | |
| 549 StringLengthStub string_length_stub(kind()); | |
| 550 stub = string_length_stub.GetCode(isolate()); | |
| 551 } else if (state() != MEGAMORPHIC) { | |
| 552 ASSERT(state() != GENERIC); | |
| 553 stub = megamorphic_stub(); | |
| 554 } | |
| 555 if (!stub.is_null()) { | |
| 556 set_target(*stub); | |
| 557 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n"); | |
| 558 } | |
| 559 // Get the string if we have a string wrapper object. | |
| 560 String* string = String::cast(JSValue::cast(*object)->value()); | |
| 561 return Smi::FromInt(string->length()); | |
| 562 } | |
| 563 | |
| 564 // Use specialized code for getting prototype of functions. | 539 // Use specialized code for getting prototype of functions. |
| 565 if (object->IsJSFunction() && | 540 if (object->IsJSFunction() && |
| 566 name->Equals(isolate()->heap()->prototype_string()) && | 541 name->Equals(isolate()->heap()->prototype_string()) && |
| 567 Handle<JSFunction>::cast(object)->should_have_prototype()) { | 542 Handle<JSFunction>::cast(object)->should_have_prototype()) { |
| 568 Handle<Code> stub; | 543 Handle<Code> stub; |
| 569 if (state() == UNINITIALIZED) { | 544 if (state() == UNINITIALIZED) { |
| 570 stub = pre_monomorphic_stub(); | 545 stub = pre_monomorphic_stub(); |
| 571 } else if (state() == PREMONOMORPHIC) { | 546 } else if (state() == PREMONOMORPHIC) { |
| 572 FunctionPrototypeStub function_prototype_stub(kind()); | 547 FunctionPrototypeStub function_prototype_stub(kind()); |
| 573 stub = function_prototype_stub.GetCode(isolate()); | 548 stub = function_prototype_stub.GetCode(isolate()); |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, | 878 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, |
| 904 Handle<Object> object, | 879 Handle<Object> object, |
| 905 Handle<String> name, | 880 Handle<String> name, |
| 906 Handle<Object> unused, | 881 Handle<Object> unused, |
| 907 InlineCacheHolderFlag cache_holder) { | 882 InlineCacheHolderFlag cache_holder) { |
| 908 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) { | 883 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) { |
| 909 int length_index = String::kLengthOffset / kPointerSize; | 884 int length_index = String::kLengthOffset / kPointerSize; |
| 910 return SimpleFieldLoad(length_index); | 885 return SimpleFieldLoad(length_index); |
| 911 } | 886 } |
| 912 | 887 |
| 888 if (object->IsStringWrapper() && |
| 889 name->Equals(isolate()->heap()->length_string())) { |
| 890 if (kind() == Code::LOAD_IC) { |
| 891 StringLengthStub string_length_stub; |
| 892 return string_length_stub.GetCode(isolate()); |
| 893 } else { |
| 894 KeyedStringLengthStub string_length_stub; |
| 895 return string_length_stub.GetCode(isolate()); |
| 896 } |
| 897 } |
| 898 |
| 913 Handle<HeapType> type = CurrentTypeOf(object, isolate()); | 899 Handle<HeapType> type = CurrentTypeOf(object, isolate()); |
| 914 Handle<JSObject> holder(lookup->holder()); | 900 Handle<JSObject> holder(lookup->holder()); |
| 915 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); | 901 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); |
| 916 | 902 |
| 917 switch (lookup->type()) { | 903 switch (lookup->type()) { |
| 918 case FIELD: { | 904 case FIELD: { |
| 919 PropertyIndex field = lookup->GetFieldIndex(); | 905 PropertyIndex field = lookup->GetFieldIndex(); |
| 920 if (object.is_identical_to(holder)) { | 906 if (object.is_identical_to(holder)) { |
| 921 return SimpleFieldLoad(field.translate(holder), | 907 return SimpleFieldLoad(field.translate(holder), |
| 922 field.is_inobject(holder), | 908 field.is_inobject(holder), |
| (...skipping 1934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2857 #undef ADDR | 2843 #undef ADDR |
| 2858 }; | 2844 }; |
| 2859 | 2845 |
| 2860 | 2846 |
| 2861 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2847 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2862 return IC_utilities[id]; | 2848 return IC_utilities[id]; |
| 2863 } | 2849 } |
| 2864 | 2850 |
| 2865 | 2851 |
| 2866 } } // namespace v8::internal | 2852 } } // namespace v8::internal |
| OLD | NEW |