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 |