Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(763)

Side by Side Diff: src/arm/stub-cache-arm.cc

Issue 12340112: Polymorphism support for load IC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/builtins.h » ('j') | src/code-stubs.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 1067
1068 1068
1069 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1069 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1070 Register object_reg, 1070 Register object_reg,
1071 Handle<JSObject> holder, 1071 Handle<JSObject> holder,
1072 Register holder_reg, 1072 Register holder_reg,
1073 Register scratch1, 1073 Register scratch1,
1074 Register scratch2, 1074 Register scratch2,
1075 Handle<String> name, 1075 Handle<String> name,
1076 int save_at_depth, 1076 int save_at_depth,
1077 Label* miss) { 1077 Label* miss,
1078 PrototypeCheckType check) {
1079 Handle<JSObject> first = object;
1078 // Make sure there's no overlap between holder and object registers. 1080 // Make sure there's no overlap between holder and object registers.
1079 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1081 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1080 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1082 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1081 && !scratch2.is(scratch1)); 1083 && !scratch2.is(scratch1));
1082 1084
1083 // Keep track of the current object in register reg. 1085 // Keep track of the current object in register reg.
1084 Register reg = object_reg; 1086 Register reg = object_reg;
1085 int depth = 0; 1087 int depth = 0;
1086 1088
1087 if (save_at_depth == depth) { 1089 if (save_at_depth == depth) {
(...skipping 21 matching lines...) Expand all
1109 StringDictionary::kNotFound); 1111 StringDictionary::kNotFound);
1110 1112
1111 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 1113 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1112 scratch1, scratch2); 1114 scratch1, scratch2);
1113 1115
1114 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 1116 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1115 reg = holder_reg; // From now on the object will be in holder_reg. 1117 reg = holder_reg; // From now on the object will be in holder_reg.
1116 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 1118 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1117 } else { 1119 } else {
1118 Handle<Map> current_map(current->map()); 1120 Handle<Map> current_map(current->map());
1119 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, 1121 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) {
1120 ALLOW_ELEMENT_TRANSITION_MAPS); 1122 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK,
1123 ALLOW_ELEMENT_TRANSITION_MAPS);
1124 }
1121 1125
1122 // Check access rights to the global object. This has to happen after 1126 // Check access rights to the global object. This has to happen after
1123 // the map check so that we know that the object is actually a global 1127 // the map check so that we know that the object is actually a global
1124 // object. 1128 // object.
1125 if (current->IsJSGlobalProxy()) { 1129 if (current->IsJSGlobalProxy()) {
1126 __ CheckAccessGlobalProxy(reg, scratch2, miss); 1130 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1127 } 1131 }
1128 reg = holder_reg; // From now on the object will be in holder_reg. 1132 reg = holder_reg; // From now on the object will be in holder_reg.
1129 1133
1130 if (heap()->InNewSpace(*prototype)) { 1134 if (heap()->InNewSpace(*prototype)) {
(...skipping 10 matching lines...) Expand all
1141 __ str(reg, MemOperand(sp)); 1145 __ str(reg, MemOperand(sp));
1142 } 1146 }
1143 1147
1144 // Go to the next object in the prototype chain. 1148 // Go to the next object in the prototype chain.
1145 current = prototype; 1149 current = prototype;
1146 } 1150 }
1147 1151
1148 // Log the check depth. 1152 // Log the check depth.
1149 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); 1153 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
1150 1154
1151 // Check the holder map. 1155 Handle<Map> current_map(current->map());
1152 __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss, 1156 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) {
1153 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); 1157 // Check the holder map.
1158 __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss,
1159 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
1160 }
1154 1161
1155 // Perform security check for access to the global object. 1162 // Perform security check for access to the global object.
1156 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1163 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1157 if (holder->IsJSGlobalProxy()) { 1164 if (holder->IsJSGlobalProxy()) {
1158 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1165 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1159 } 1166 }
1160 1167
1161 // If we've skipped any global objects, it's not enough to verify that 1168 // If we've skipped any global objects, it's not enough to verify that
1162 // their maps haven't changed. We also need to check that the property 1169 // their maps haven't changed. We also need to check that the property
1163 // cell for the property is still empty. 1170 // cell for the property is still empty.
(...skipping 1811 matching lines...) Expand 10 before | Expand all | Expand 10 after
2975 } 2982 }
2976 2983
2977 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 2984 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
2978 __ Jump(ic, RelocInfo::CODE_TARGET); 2985 __ Jump(ic, RelocInfo::CODE_TARGET);
2979 2986
2980 // Return the generated code. 2987 // Return the generated code.
2981 return GetCode(Code::NORMAL, factory()->empty_string()); 2988 return GetCode(Code::NORMAL, factory()->empty_string());
2982 } 2989 }
2983 2990
2984 2991
2985 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( 2992 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
2986 MapHandleList* receiver_maps, 2993 MapHandleList* receiver_maps,
2987 CodeHandleList* handler_ics) { 2994 CodeHandleList* handlers,
2988 // ----------- S t a t e ------------- 2995 Handle<String> name) {
2989 // -- lr : return address
2990 // -- r0 : key
2991 // -- r1 : receiver
2992 // -----------------------------------
2993 Label miss; 2996 Label miss;
2994 __ JumpIfSmi(r1, &miss); 2997 __ JumpIfSmi(receiver(), &miss);
2995 2998
2996 int receiver_count = receiver_maps->length(); 2999 int receiver_count = receiver_maps->length();
2997 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 3000 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
2998 for (int current = 0; current < receiver_count; ++current) { 3001 for (int current = 0; current < receiver_count; ++current) {
2999 __ mov(ip, Operand(receiver_maps->at(current))); 3002 __ mov(ip, Operand(receiver_maps->at(current)));
3000 __ cmp(r2, ip); 3003 __ cmp(scratch1(), ip);
3001 __ Jump(handler_ics->at(current), RelocInfo::CODE_TARGET, eq); 3004 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq);
3002 } 3005 }
3003 3006
3004 __ bind(&miss); 3007 __ bind(&miss);
3005 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); 3008 GenerateLoadMiss(masm(), kind());
3006 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
3007 3009
3008 // Return the generated code. 3010 // Return the generated code.
3009 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3011 InlineCacheState state =
3012 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
3013 return GetCode(type, name, state);
3010 } 3014 }
3011 3015
3012 3016
3013 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, 3017 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
3014 int index, 3018 int index,
3015 Handle<Map> transition, 3019 Handle<Map> transition,
3016 Handle<String> name) { 3020 Handle<String> name) {
3017 // ----------- S t a t e ------------- 3021 // ----------- S t a t e -------------
3018 // -- r0 : value 3022 // -- r0 : value
3019 // -- r1 : name 3023 // -- r1 : name
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
4054 __ Jump(ic_slow, RelocInfo::CODE_TARGET); 4058 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
4055 } 4059 }
4056 } 4060 }
4057 4061
4058 4062
4059 #undef __ 4063 #undef __
4060 4064
4061 } } // namespace v8::internal 4065 } } // namespace v8::internal
4062 4066
4063 #endif // V8_TARGET_ARCH_ARM 4067 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/builtins.h » ('j') | src/code-stubs.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698