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

Side by Side Diff: src/ic/ic.cc

Issue 540903002: Flatten property_kind into state. Add UNKNOWN as a state for dict-mode receivers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add DCHECKs Created 6 years, 3 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 | « src/ic/ia32/handler-compiler-ia32.cc ('k') | src/ic/mips/handler-compiler-mips.cc » ('j') | no next file with comments »
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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 DCHECK(original_code->IsCode()); 208 DCHECK(original_code->IsCode());
209 return original_code; 209 return original_code;
210 } 210 }
211 211
212 212
213 static void LookupForRead(LookupIterator* it) { 213 static void LookupForRead(LookupIterator* it) {
214 for (; it->IsFound(); it->Next()) { 214 for (; it->IsFound(); it->Next()) {
215 switch (it->state()) { 215 switch (it->state()) {
216 case LookupIterator::NOT_FOUND: 216 case LookupIterator::NOT_FOUND:
217 case LookupIterator::TRANSITION: 217 case LookupIterator::TRANSITION:
218 case LookupIterator::UNKNOWN:
218 UNREACHABLE(); 219 UNREACHABLE();
219 case LookupIterator::JSPROXY: 220 case LookupIterator::JSPROXY:
220 return; 221 return;
221 case LookupIterator::INTERCEPTOR: { 222 case LookupIterator::INTERCEPTOR: {
222 // If there is a getter, return; otherwise loop to perform the lookup. 223 // If there is a getter, return; otherwise loop to perform the lookup.
223 Handle<JSObject> holder = it->GetHolder<JSObject>(); 224 Handle<JSObject> holder = it->GetHolder<JSObject>();
224 if (!holder->GetNamedInterceptor()->getter()->IsUndefined()) { 225 if (!holder->GetNamedInterceptor()->getter()->IsUndefined()) {
225 return; 226 return;
226 } 227 }
227 break; 228 break;
228 } 229 }
229 case LookupIterator::ACCESS_CHECK: 230 case LookupIterator::ACCESS_CHECK:
230 // PropertyHandlerCompiler::CheckPrototypes() knows how to emit 231 // PropertyHandlerCompiler::CheckPrototypes() knows how to emit
231 // access checks for global proxies. 232 // access checks for global proxies.
232 if (it->GetHolder<JSObject>()->IsJSGlobalProxy() && 233 if (it->GetHolder<JSObject>()->IsJSGlobalProxy() &&
233 it->HasAccess(v8::ACCESS_GET)) { 234 it->HasAccess(v8::ACCESS_GET)) {
234 break; 235 break;
235 } 236 }
236 return; 237 return;
237 case LookupIterator::PROPERTY: 238 case LookupIterator::ACCESSOR:
238 if (it->HasProperty()) return; // Yay! 239 case LookupIterator::DATA:
239 break; 240 return;
240 } 241 }
241 } 242 }
242 } 243 }
243 244
244 245
245 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 246 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
246 Handle<String> name) { 247 Handle<String> name) {
247 if (!IsNameCompatibleWithPrototypeFailure(name)) return false; 248 if (!IsNameCompatibleWithPrototypeFailure(name)) return false;
248 Handle<Map> receiver_map = TypeToMap(*receiver_type(), isolate()); 249 Handle<Map> receiver_map = TypeToMap(*receiver_type(), isolate());
249 maybe_handler_ = target()->FindHandlerForMap(*receiver_map); 250 maybe_handler_ = target()->FindHandlerForMap(*receiver_map);
(...skipping 28 matching lines...) Expand all
278 int index = ic_holder_map->IndexInCodeCache(*name, *target()); 279 int index = ic_holder_map->IndexInCodeCache(*name, *target());
279 if (index >= 0) { 280 if (index >= 0) {
280 ic_holder_map->RemoveFromCodeCache(*name, *target(), index); 281 ic_holder_map->RemoveFromCodeCache(*name, *target(), index);
281 } 282 }
282 } 283 }
283 284
284 if (receiver->IsGlobalObject()) { 285 if (receiver->IsGlobalObject()) {
285 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 286 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
286 LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); 287 LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
287 if (it.state() == LookupIterator::ACCESS_CHECK) return false; 288 if (it.state() == LookupIterator::ACCESS_CHECK) return false;
288 if (!it.IsFound() || !it.HasProperty()) return false; 289 if (!it.IsFound()) return false;
289 Handle<PropertyCell> cell = it.GetPropertyCell(); 290 Handle<PropertyCell> cell = it.GetPropertyCell();
290 return cell->type()->IsConstant(); 291 return cell->type()->IsConstant();
291 } 292 }
292 293
293 return true; 294 return true;
294 } 295 }
295 296
296 297
297 bool IC::IsNameCompatibleWithPrototypeFailure(Handle<Object> name) { 298 bool IC::IsNameCompatibleWithPrototypeFailure(Handle<Object> name) {
298 if (target()->is_keyed_stub()) { 299 if (target()->is_keyed_stub()) {
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 cache_holder); 970 cache_holder);
970 // Perform a lookup behind the interceptor. Copy the LookupIterator since 971 // Perform a lookup behind the interceptor. Copy the LookupIterator since
971 // the original iterator will be used to fetch the value. 972 // the original iterator will be used to fetch the value.
972 LookupIterator it = *lookup; 973 LookupIterator it = *lookup;
973 it.Next(); 974 it.Next();
974 LookupForRead(&it); 975 LookupForRead(&it);
975 return compiler.CompileLoadInterceptor(&it); 976 return compiler.CompileLoadInterceptor(&it);
976 } 977 }
977 978
978 // -------------- Accessors -------------- 979 // -------------- Accessors --------------
979 DCHECK(lookup->state() == LookupIterator::PROPERTY); 980 if (lookup->state() == LookupIterator::ACCESSOR) {
980 if (lookup->property_kind() == LookupIterator::ACCESSOR) {
981 // Use simple field loads for some well-known callback properties. 981 // Use simple field loads for some well-known callback properties.
982 if (receiver_is_holder) { 982 if (receiver_is_holder) {
983 DCHECK(receiver->IsJSObject()); 983 DCHECK(receiver->IsJSObject());
984 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); 984 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver);
985 int object_offset; 985 int object_offset;
986 if (Accessors::IsJSObjectFieldAccessor<HeapType>(type, lookup->name(), 986 if (Accessors::IsJSObjectFieldAccessor<HeapType>(type, lookup->name(),
987 &object_offset)) { 987 &object_offset)) {
988 FieldIndex index = 988 FieldIndex index =
989 FieldIndex::ForInObjectOffset(object_offset, js_receiver->map()); 989 FieldIndex::ForInObjectOffset(object_offset, js_receiver->map());
990 return SimpleFieldLoad(index); 990 return SimpleFieldLoad(index);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 return compiler.CompileLoadCallback(lookup->name(), call_optimization); 1025 return compiler.CompileLoadCallback(lookup->name(), call_optimization);
1026 } 1026 }
1027 return compiler.CompileLoadViaGetter(lookup->name(), function); 1027 return compiler.CompileLoadViaGetter(lookup->name(), function);
1028 } 1028 }
1029 // TODO(dcarney): Handle correctly. 1029 // TODO(dcarney): Handle correctly.
1030 DCHECK(accessors->IsDeclaredAccessorInfo()); 1030 DCHECK(accessors->IsDeclaredAccessorInfo());
1031 return slow_stub(); 1031 return slow_stub();
1032 } 1032 }
1033 1033
1034 // -------------- Dictionary properties -------------- 1034 // -------------- Dictionary properties --------------
1035 DCHECK(lookup->property_kind() == LookupIterator::DATA); 1035 DCHECK(lookup->state() == LookupIterator::DATA);
1036 if (lookup->property_encoding() == LookupIterator::DICTIONARY) { 1036 if (lookup->property_encoding() == LookupIterator::DICTIONARY) {
1037 if (kind() != Code::LOAD_IC) return slow_stub(); 1037 if (kind() != Code::LOAD_IC) return slow_stub();
1038 if (holder->IsGlobalObject()) { 1038 if (holder->IsGlobalObject()) {
1039 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 1039 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder,
1040 cache_holder); 1040 cache_holder);
1041 Handle<PropertyCell> cell = lookup->GetPropertyCell(); 1041 Handle<PropertyCell> cell = lookup->GetPropertyCell();
1042 Handle<Code> code = compiler.CompileLoadGlobal(cell, lookup->name(), 1042 Handle<Code> code = compiler.CompileLoadGlobal(cell, lookup->name(),
1043 lookup->IsConfigurable()); 1043 lookup->IsConfigurable());
1044 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1044 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1045 CacheHolderFlag flag; 1045 CacheHolderFlag flag;
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 JSReceiver::StoreFromKeyed store_mode) { 1216 JSReceiver::StoreFromKeyed store_mode) {
1217 // Disable ICs for non-JSObjects for now. 1217 // Disable ICs for non-JSObjects for now.
1218 Handle<Object> receiver = it->GetReceiver(); 1218 Handle<Object> receiver = it->GetReceiver();
1219 if (!receiver->IsJSObject()) return false; 1219 if (!receiver->IsJSObject()) return false;
1220 DCHECK(!Handle<JSObject>::cast(receiver)->map()->is_deprecated()); 1220 DCHECK(!Handle<JSObject>::cast(receiver)->map()->is_deprecated());
1221 1221
1222 for (; it->IsFound(); it->Next()) { 1222 for (; it->IsFound(); it->Next()) {
1223 switch (it->state()) { 1223 switch (it->state()) {
1224 case LookupIterator::NOT_FOUND: 1224 case LookupIterator::NOT_FOUND:
1225 case LookupIterator::TRANSITION: 1225 case LookupIterator::TRANSITION:
1226 case LookupIterator::UNKNOWN:
1226 UNREACHABLE(); 1227 UNREACHABLE();
1227 case LookupIterator::JSPROXY: 1228 case LookupIterator::JSPROXY:
1228 return false; 1229 return false;
1229 case LookupIterator::INTERCEPTOR: { 1230 case LookupIterator::INTERCEPTOR: {
1230 Handle<JSObject> holder = it->GetHolder<JSObject>(); 1231 Handle<JSObject> holder = it->GetHolder<JSObject>();
1231 InterceptorInfo* info = holder->GetNamedInterceptor(); 1232 InterceptorInfo* info = holder->GetNamedInterceptor();
1232 if (it->HolderIsReceiverOrHiddenPrototype()) { 1233 if (it->HolderIsReceiverOrHiddenPrototype()) {
1233 if (!info->setter()->IsUndefined()) return true; 1234 if (!info->setter()->IsUndefined()) return true;
1234 } else if (!info->getter()->IsUndefined() || 1235 } else if (!info->getter()->IsUndefined() ||
1235 !info->query()->IsUndefined()) { 1236 !info->query()->IsUndefined()) {
1236 return false; 1237 return false;
1237 } 1238 }
1238 break; 1239 break;
1239 } 1240 }
1240 case LookupIterator::ACCESS_CHECK: 1241 case LookupIterator::ACCESS_CHECK:
1241 if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false; 1242 if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false;
1242 break; 1243 break;
1243 case LookupIterator::PROPERTY: 1244 case LookupIterator::ACCESSOR:
1244 if (!it->HasProperty()) break; 1245 return !it->IsReadOnly();
1246 case LookupIterator::DATA: {
1245 if (it->IsReadOnly()) return false; 1247 if (it->IsReadOnly()) return false;
1246 if (it->property_kind() == LookupIterator::ACCESSOR) return true; 1248 Handle<JSObject> holder = it->GetHolder<JSObject>();
1247 if (it->GetHolder<Object>().is_identical_to(receiver)) { 1249 if (receiver.is_identical_to(holder)) {
1248 it->PrepareForDataProperty(value); 1250 it->PrepareForDataProperty(value);
1249 // The previous receiver map might just have been deprecated, 1251 // The previous receiver map might just have been deprecated,
1250 // so reload it. 1252 // so reload it.
1251 update_receiver_type(receiver); 1253 update_receiver_type(receiver);
1252 return true; 1254 return true;
1253 } 1255 }
1254 1256
1255 // Receiver != holder. 1257 // Receiver != holder.
1258 PrototypeIterator iter(it->isolate(), receiver);
1256 if (receiver->IsJSGlobalProxy()) { 1259 if (receiver->IsJSGlobalProxy()) {
1257 PrototypeIterator iter(it->isolate(), receiver);
1258 return it->GetHolder<Object>().is_identical_to( 1260 return it->GetHolder<Object>().is_identical_to(
1259 PrototypeIterator::GetCurrent(iter)); 1261 PrototypeIterator::GetCurrent(iter));
1260 } 1262 }
1261 1263
1262 it->PrepareTransitionToDataProperty(value, NONE, store_mode); 1264 it->PrepareTransitionToDataProperty(value, NONE, store_mode);
1263 return it->IsCacheableTransition(); 1265 return it->IsCacheableTransition();
1266 }
1264 } 1267 }
1265 } 1268 }
1266 1269
1267 it->PrepareTransitionToDataProperty(value, NONE, store_mode); 1270 it->PrepareTransitionToDataProperty(value, NONE, store_mode);
1268 return it->IsCacheableTransition(); 1271 return it->IsCacheableTransition();
1269 } 1272 }
1270 1273
1271 1274
1272 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, 1275 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
1273 Handle<Object> value, 1276 Handle<Object> value,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 } 1413 }
1411 1414
1412 // -------------- Interceptors -------------- 1415 // -------------- Interceptors --------------
1413 if (lookup->state() == LookupIterator::INTERCEPTOR) { 1416 if (lookup->state() == LookupIterator::INTERCEPTOR) {
1414 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); 1417 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined());
1415 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1418 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder);
1416 return compiler.CompileStoreInterceptor(lookup->name()); 1419 return compiler.CompileStoreInterceptor(lookup->name());
1417 } 1420 }
1418 1421
1419 // -------------- Accessors -------------- 1422 // -------------- Accessors --------------
1420 DCHECK(lookup->state() == LookupIterator::PROPERTY); 1423 if (lookup->state() == LookupIterator::ACCESSOR) {
1421 if (lookup->property_kind() == LookupIterator::ACCESSOR) {
1422 if (!holder->HasFastProperties()) return slow_stub(); 1424 if (!holder->HasFastProperties()) return slow_stub();
1423 Handle<Object> accessors = lookup->GetAccessors(); 1425 Handle<Object> accessors = lookup->GetAccessors();
1424 if (accessors->IsExecutableAccessorInfo()) { 1426 if (accessors->IsExecutableAccessorInfo()) {
1425 Handle<ExecutableAccessorInfo> info = 1427 Handle<ExecutableAccessorInfo> info =
1426 Handle<ExecutableAccessorInfo>::cast(accessors); 1428 Handle<ExecutableAccessorInfo>::cast(accessors);
1427 if (v8::ToCData<Address>(info->setter()) == 0) return slow_stub(); 1429 if (v8::ToCData<Address>(info->setter()) == 0) return slow_stub();
1428 if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info, 1430 if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info,
1429 receiver_type())) { 1431 receiver_type())) {
1430 return slow_stub(); 1432 return slow_stub();
1431 } 1433 }
(...skipping 13 matching lines...) Expand all
1445 } 1447 }
1446 return compiler.CompileStoreViaSetter(receiver, lookup->name(), 1448 return compiler.CompileStoreViaSetter(receiver, lookup->name(),
1447 Handle<JSFunction>::cast(setter)); 1449 Handle<JSFunction>::cast(setter));
1448 } 1450 }
1449 // TODO(dcarney): Handle correctly. 1451 // TODO(dcarney): Handle correctly.
1450 DCHECK(accessors->IsDeclaredAccessorInfo()); 1452 DCHECK(accessors->IsDeclaredAccessorInfo());
1451 return slow_stub(); 1453 return slow_stub();
1452 } 1454 }
1453 1455
1454 // -------------- Dictionary properties -------------- 1456 // -------------- Dictionary properties --------------
1455 DCHECK(lookup->property_kind() == LookupIterator::DATA); 1457 DCHECK(lookup->state() == LookupIterator::DATA);
1456 if (lookup->property_encoding() == LookupIterator::DICTIONARY) { 1458 if (lookup->property_encoding() == LookupIterator::DICTIONARY) {
1457 if (holder->IsGlobalObject()) { 1459 if (holder->IsGlobalObject()) {
1458 Handle<PropertyCell> cell = lookup->GetPropertyCell(); 1460 Handle<PropertyCell> cell = lookup->GetPropertyCell();
1459 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); 1461 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
1460 StoreGlobalStub stub(isolate(), union_type->IsConstant(), 1462 StoreGlobalStub stub(isolate(), union_type->IsConstant(),
1461 receiver->IsJSGlobalProxy()); 1463 receiver->IsJSGlobalProxy());
1462 Handle<Code> code = stub.GetCodeCopyFromTemplate( 1464 Handle<Code> code = stub.GetCodeCopyFromTemplate(
1463 Handle<GlobalObject>::cast(holder), cell); 1465 Handle<GlobalObject>::cast(holder), cell);
1464 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1466 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1465 HeapObject::UpdateMapCodeCache(receiver, lookup->name(), code); 1467 HeapObject::UpdateMapCodeCache(receiver, lookup->name(), code);
(...skipping 1733 matching lines...) Expand 10 before | Expand all | Expand 10 after
3199 static const Address IC_utilities[] = { 3201 static const Address IC_utilities[] = {
3200 #define ADDR(name) FUNCTION_ADDR(name), 3202 #define ADDR(name) FUNCTION_ADDR(name),
3201 IC_UTIL_LIST(ADDR) NULL 3203 IC_UTIL_LIST(ADDR) NULL
3202 #undef ADDR 3204 #undef ADDR
3203 }; 3205 };
3204 3206
3205 3207
3206 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 3208 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
3207 } 3209 }
3208 } // namespace v8::internal 3210 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ia32/handler-compiler-ia32.cc ('k') | src/ic/mips/handler-compiler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698