| 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 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 | 912 |
| 913 | 913 |
| 914 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 914 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 915 Register object_reg, | 915 Register object_reg, |
| 916 Handle<JSObject> holder, | 916 Handle<JSObject> holder, |
| 917 Register holder_reg, | 917 Register holder_reg, |
| 918 Register scratch1, | 918 Register scratch1, |
| 919 Register scratch2, | 919 Register scratch2, |
| 920 Handle<String> name, | 920 Handle<String> name, |
| 921 int save_at_depth, | 921 int save_at_depth, |
| 922 Label* miss) { | 922 Label* miss, |
| 923 PrototypeCheckType check) { |
| 924 Handle<JSObject> first = object; |
| 923 // Make sure there's no overlap between holder and object registers. | 925 // Make sure there's no overlap between holder and object registers. |
| 924 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 926 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 925 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 927 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 926 && !scratch2.is(scratch1)); | 928 && !scratch2.is(scratch1)); |
| 927 | 929 |
| 928 // Keep track of the current object in register reg. On the first | 930 // Keep track of the current object in register reg. On the first |
| 929 // iteration, reg is an alias for object_reg, on later iterations, | 931 // iteration, reg is an alias for object_reg, on later iterations, |
| 930 // it is an alias for holder_reg. | 932 // it is an alias for holder_reg. |
| 931 Register reg = object_reg; | 933 Register reg = object_reg; |
| 932 int depth = 0; | 934 int depth = 0; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 961 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 963 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
| 962 reg = holder_reg; // From now on the object will be in holder_reg. | 964 reg = holder_reg; // From now on the object will be in holder_reg. |
| 963 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 965 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
| 964 } else { | 966 } else { |
| 965 bool in_new_space = heap()->InNewSpace(*prototype); | 967 bool in_new_space = heap()->InNewSpace(*prototype); |
| 966 Handle<Map> current_map(current->map()); | 968 Handle<Map> current_map(current->map()); |
| 967 if (in_new_space) { | 969 if (in_new_space) { |
| 968 // Save the map in scratch1 for later. | 970 // Save the map in scratch1 for later. |
| 969 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 971 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
| 970 } | 972 } |
| 971 __ CheckMap(reg, Handle<Map>(current_map), | 973 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { |
| 972 miss, DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); | 974 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK, |
| 975 ALLOW_ELEMENT_TRANSITION_MAPS); |
| 976 } |
| 973 | 977 |
| 974 // Check access rights to the global object. This has to happen after | 978 // Check access rights to the global object. This has to happen after |
| 975 // the map check so that we know that the object is actually a global | 979 // the map check so that we know that the object is actually a global |
| 976 // object. | 980 // object. |
| 977 if (current->IsJSGlobalProxy()) { | 981 if (current->IsJSGlobalProxy()) { |
| 978 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 982 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 979 } | 983 } |
| 980 reg = holder_reg; // From now on the object will be in holder_reg. | 984 reg = holder_reg; // From now on the object will be in holder_reg. |
| 981 | 985 |
| 982 if (in_new_space) { | 986 if (in_new_space) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 __ push(reg); // holder | 1134 __ push(reg); // holder |
| 1131 if (heap()->InNewSpace(callback->data())) { | 1135 if (heap()->InNewSpace(callback->data())) { |
| 1132 __ Move(scratch1(), callback); | 1136 __ Move(scratch1(), callback); |
| 1133 __ push(FieldOperand(scratch1(), | 1137 __ push(FieldOperand(scratch1(), |
| 1134 ExecutableAccessorInfo::kDataOffset)); // data | 1138 ExecutableAccessorInfo::kDataOffset)); // data |
| 1135 } else { | 1139 } else { |
| 1136 __ Push(Handle<Object>(callback->data(), isolate())); | 1140 __ Push(Handle<Object>(callback->data(), isolate())); |
| 1137 } | 1141 } |
| 1138 __ PushAddress(ExternalReference::isolate_address()); // isolate | 1142 __ PushAddress(ExternalReference::isolate_address()); // isolate |
| 1139 __ push(name()); // name | 1143 __ push(name()); // name |
| 1140 // Save a pointer to where we pushed the arguments pointer. | 1144 // Save a pointer to where we pushed the arguments pointer. This will be |
| 1141 // This will be passed as the const AccessorInfo& to the C++ callback. | 1145 // passed as the const ExecutableAccessorInfo& to the C++ callback. |
| 1142 | 1146 |
| 1143 #if defined(__MINGW64__) | 1147 #if defined(__MINGW64__) |
| 1144 Register accessor_info_arg = rdx; | 1148 Register accessor_info_arg = rdx; |
| 1145 Register name_arg = rcx; | 1149 Register name_arg = rcx; |
| 1146 #elif defined(_WIN64) | 1150 #elif defined(_WIN64) |
| 1147 // Win64 uses first register--rcx--for returned value. | 1151 // Win64 uses first register--rcx--for returned value. |
| 1148 Register accessor_info_arg = r8; | 1152 Register accessor_info_arg = r8; |
| 1149 Register name_arg = rdx; | 1153 Register name_arg = rdx; |
| 1150 #else | 1154 #else |
| 1151 Register accessor_info_arg = rsi; | 1155 Register accessor_info_arg = rsi; |
| (...skipping 1723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2875 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); | 2879 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); |
| 2876 } | 2880 } |
| 2877 | 2881 |
| 2878 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2882 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 2879 | 2883 |
| 2880 // Return the generated code. | 2884 // Return the generated code. |
| 2881 return GetCode(Code::NORMAL, factory()->empty_string()); | 2885 return GetCode(Code::NORMAL, factory()->empty_string()); |
| 2882 } | 2886 } |
| 2883 | 2887 |
| 2884 | 2888 |
| 2885 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( | 2889 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
| 2886 MapHandleList* receiver_maps, | 2890 MapHandleList* receiver_maps, |
| 2887 CodeHandleList* handler_ics) { | 2891 CodeHandleList* handlers, |
| 2888 // ----------- S t a t e ------------- | 2892 Handle<String> name, |
| 2889 // -- rax : key | 2893 Code::StubType type) { |
| 2890 // -- rdx : receiver | |
| 2891 // -- rsp[0] : return address | |
| 2892 // ----------------------------------- | |
| 2893 Label miss; | 2894 Label miss; |
| 2894 __ JumpIfSmi(rdx, &miss); | 2895 __ JumpIfSmi(receiver(), &miss); |
| 2895 | 2896 |
| 2896 Register map_reg = rbx; | 2897 Register map_reg = scratch1(); |
| 2897 __ movq(map_reg, FieldOperand(rdx, HeapObject::kMapOffset)); | 2898 __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); |
| 2898 int receiver_count = receiver_maps->length(); | 2899 int receiver_count = receiver_maps->length(); |
| 2899 for (int current = 0; current < receiver_count; ++current) { | 2900 for (int current = 0; current < receiver_count; ++current) { |
| 2900 // Check map and tail call if there's a match | 2901 // Check map and tail call if there's a match |
| 2901 __ Cmp(map_reg, receiver_maps->at(current)); | 2902 __ Cmp(map_reg, receiver_maps->at(current)); |
| 2902 __ j(equal, handler_ics->at(current), RelocInfo::CODE_TARGET); | 2903 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET); |
| 2903 } | 2904 } |
| 2904 | 2905 |
| 2905 __ bind(&miss); | 2906 __ bind(&miss); |
| 2906 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2907 GenerateLoadMiss(masm(), kind()); |
| 2907 | 2908 |
| 2908 // Return the generated code. | 2909 // Return the generated code. |
| 2909 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 2910 InlineCacheState state = |
| 2911 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; |
| 2912 return GetCode(type, name, state); |
| 2910 } | 2913 } |
| 2911 | 2914 |
| 2912 | 2915 |
| 2913 // Specialized stub for constructing objects from functions which only have only | 2916 // Specialized stub for constructing objects from functions which only have only |
| 2914 // simple assignments of the form this.x = ...; in their body. | 2917 // simple assignments of the form this.x = ...; in their body. |
| 2915 Handle<Code> ConstructStubCompiler::CompileConstructStub( | 2918 Handle<Code> ConstructStubCompiler::CompileConstructStub( |
| 2916 Handle<JSFunction> function) { | 2919 Handle<JSFunction> function) { |
| 2917 // ----------- S t a t e ------------- | 2920 // ----------- S t a t e ------------- |
| 2918 // -- rax : argc | 2921 // -- rax : argc |
| 2919 // -- rdi : constructor | 2922 // -- rdi : constructor |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3582 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3585 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
| 3583 } | 3586 } |
| 3584 } | 3587 } |
| 3585 | 3588 |
| 3586 | 3589 |
| 3587 #undef __ | 3590 #undef __ |
| 3588 | 3591 |
| 3589 } } // namespace v8::internal | 3592 } } // namespace v8::internal |
| 3590 | 3593 |
| 3591 #endif // V8_TARGET_ARCH_X64 | 3594 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |