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

Side by Side Diff: src/ic.cc

Issue 8341008: Handlify upper layers of StoreIC based on 8337008. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased. Created 9 years, 2 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.h ('k') | src/stub-cache.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false; 1364 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;
1365 1365
1366 // If the property is read-only, we leave the IC in its current 1366 // If the property is read-only, we leave the IC in its current
1367 // state. 1367 // state.
1368 if (lookup->IsReadOnly()) return false; 1368 if (lookup->IsReadOnly()) return false;
1369 1369
1370 return true; 1370 return true;
1371 } 1371 }
1372 1372
1373 1373
1374 static bool LookupForWrite(JSObject* receiver, 1374 static bool LookupForWrite(Handle<JSObject> receiver,
1375 String* name, 1375 Handle<String> name,
1376 LookupResult* lookup) { 1376 LookupResult* lookup) {
1377 receiver->LocalLookup(name, lookup); 1377 receiver->LocalLookup(*name, lookup);
1378 if (!StoreICableLookup(lookup)) { 1378 if (!StoreICableLookup(lookup)) {
1379 return false; 1379 return false;
1380 } 1380 }
1381 1381
1382 if (lookup->type() == INTERCEPTOR && 1382 if (lookup->type() == INTERCEPTOR &&
1383 receiver->GetNamedInterceptor()->setter()->IsUndefined()) { 1383 receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
1384 receiver->LocalLookupRealNamedProperty(name, lookup); 1384 receiver->LocalLookupRealNamedProperty(*name, lookup);
1385 return StoreICableLookup(lookup); 1385 return StoreICableLookup(lookup);
1386 } 1386 }
1387 1387
1388 return true; 1388 return true;
1389 } 1389 }
1390 1390
1391 1391
1392 MaybeObject* StoreIC::Store(State state, 1392 MaybeObject* StoreIC::Store(State state,
1393 StrictModeFlag strict_mode, 1393 StrictModeFlag strict_mode,
1394 Handle<Object> object, 1394 Handle<Object> object,
(...skipping 20 matching lines...) Expand all
1415 // Ignore other stores where the receiver is not a JSObject. 1415 // Ignore other stores where the receiver is not a JSObject.
1416 // TODO(1475): Must check prototype chains of object wrappers. 1416 // TODO(1475): Must check prototype chains of object wrappers.
1417 return *value; 1417 return *value;
1418 } 1418 }
1419 1419
1420 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1420 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1421 1421
1422 // Check if the given name is an array index. 1422 // Check if the given name is an array index.
1423 uint32_t index; 1423 uint32_t index;
1424 if (name->AsArrayIndex(&index)) { 1424 if (name->AsArrayIndex(&index)) {
1425 HandleScope scope(isolate());
1426 Handle<Object> result = SetElement(receiver, index, value, strict_mode); 1425 Handle<Object> result = SetElement(receiver, index, value, strict_mode);
1427 if (result.is_null()) return Failure::Exception(); 1426 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1428 return *value; 1427 return *value;
1429 } 1428 }
1430 1429
1431 // Use specialized code for setting the length of arrays. 1430 // Use specialized code for setting the length of arrays.
1432 if (receiver->IsJSArray() 1431 if (receiver->IsJSArray()
1433 && name->Equals(isolate()->heap()->length_symbol()) 1432 && name->Equals(isolate()->heap()->length_symbol())
1434 && JSArray::cast(*receiver)->AllowsSetElementsLength()) { 1433 && Handle<JSArray>::cast(receiver)->AllowsSetElementsLength()) {
1435 #ifdef DEBUG 1434 #ifdef DEBUG
1436 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); 1435 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
1437 #endif 1436 #endif
1438 Builtins::Name target = (strict_mode == kStrictMode) 1437 Handle<Code> stub = (strict_mode == kStrictMode)
1439 ? Builtins::kStoreIC_ArrayLength_Strict 1438 ? isolate()->builtins()->StoreIC_ArrayLength_Strict()
1440 : Builtins::kStoreIC_ArrayLength; 1439 : isolate()->builtins()->StoreIC_ArrayLength();
1441 set_target(isolate()->builtins()->builtin(target)); 1440 set_target(*stub);
1442 return receiver->SetProperty(*name, *value, NONE, strict_mode); 1441 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1443 } 1442 }
1444 1443
1445 // Lookup the property locally in the receiver. 1444 // Lookup the property locally in the receiver.
1446 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { 1445 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1447 LookupResult lookup(isolate()); 1446 LookupResult lookup(isolate());
1448 if (LookupForWrite(*receiver, *name, &lookup)) { 1447
1448 if (LookupForWrite(receiver, name, &lookup)) {
1449 // Generate a stub for this store. 1449 // Generate a stub for this store.
1450 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); 1450 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1451 } else { 1451 } else {
1452 // Strict mode doesn't allow setting non-existent global property 1452 // Strict mode doesn't allow setting non-existent global property
1453 // or an assignment to a read only property. 1453 // or an assignment to a read only property.
1454 if (strict_mode == kStrictMode) { 1454 if (strict_mode == kStrictMode) {
1455 if (lookup.IsFound() && lookup.IsReadOnly()) { 1455 if (lookup.IsFound() && lookup.IsReadOnly()) {
1456 return TypeError("strict_read_only_property", object, name); 1456 return TypeError("strict_read_only_property", object, name);
1457 } else if (IsContextual(object)) { 1457 } else if (IsContextual(object)) {
1458 return ReferenceError("not_defined", name); 1458 return ReferenceError("not_defined", name);
1459 } 1459 }
1460 } 1460 }
1461 } 1461 }
1462 } 1462 }
1463 1463
1464 if (receiver->IsJSGlobalProxy()) { 1464 if (receiver->IsJSGlobalProxy()) {
1465 // TODO(ulan): find out why we patch this site even with --no-use-ic
1465 // Generate a generic stub that goes to the runtime when we see a global 1466 // Generate a generic stub that goes to the runtime when we see a global
1466 // proxy as receiver. 1467 // proxy as receiver.
1467 Code* stub = (strict_mode == kStrictMode) 1468 Handle<Code> stub = (strict_mode == kStrictMode)
1468 ? global_proxy_stub_strict() 1469 ? global_proxy_stub_strict()
1469 : global_proxy_stub(); 1470 : global_proxy_stub();
1470 if (target() != stub) { 1471 if (target() != *stub) {
1471 set_target(stub); 1472 set_target(*stub);
1472 #ifdef DEBUG 1473 #ifdef DEBUG
1473 TraceIC("StoreIC", name, state, target()); 1474 TraceIC("StoreIC", name, state, target());
1474 #endif 1475 #endif
1475 } 1476 }
1476 } 1477 }
1477 1478
1478 // Set the property. 1479 // Set the property.
1479 return receiver->SetProperty(*name, *value, NONE, strict_mode); 1480 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1480 } 1481 }
1481 1482
(...skipping 10 matching lines...) Expand all
1492 ASSERT(StoreICableLookup(lookup)); 1493 ASSERT(StoreICableLookup(lookup));
1493 1494
1494 // If the property has a non-field type allowing map transitions 1495 // If the property has a non-field type allowing map transitions
1495 // where there is extra room in the object, we leave the IC in its 1496 // where there is extra room in the object, we leave the IC in its
1496 // current state. 1497 // current state.
1497 PropertyType type = lookup->type(); 1498 PropertyType type = lookup->type();
1498 1499
1499 // Compute the code stub for this store; used for rewriting to 1500 // Compute the code stub for this store; used for rewriting to
1500 // monomorphic state and making sure that the code stub is in the 1501 // monomorphic state and making sure that the code stub is in the
1501 // stub cache. 1502 // stub cache.
1502 MaybeObject* maybe_code = NULL; 1503 Handle<Code> code;
1503 Object* code = NULL;
1504 switch (type) { 1504 switch (type) {
1505 case FIELD: { 1505 case FIELD:
1506 maybe_code = isolate()->stub_cache()->ComputeStoreField( 1506 code = isolate()->stub_cache()->ComputeStoreField(name,
1507 *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode); 1507 receiver,
1508 lookup->GetFieldIndex(),
1509 Handle<Map>::null(),
1510 strict_mode);
1508 break; 1511 break;
1509 }
1510 case MAP_TRANSITION: { 1512 case MAP_TRANSITION: {
1511 if (lookup->GetAttributes() != NONE) return; 1513 if (lookup->GetAttributes() != NONE) return;
1512 HandleScope scope(isolate());
1513 ASSERT(type == MAP_TRANSITION); 1514 ASSERT(type == MAP_TRANSITION);
1514 Handle<Map> transition(lookup->GetTransitionMap()); 1515 Handle<Map> transition(lookup->GetTransitionMap());
1515 int index = transition->PropertyIndexFor(*name); 1516 int index = transition->PropertyIndexFor(*name);
1516 maybe_code = isolate()->stub_cache()->ComputeStoreField( 1517 code = isolate()->stub_cache()->ComputeStoreField(
1517 *name, *receiver, index, *transition, strict_mode); 1518 name, receiver, index, transition, strict_mode);
1518 break; 1519 break;
1519 } 1520 }
1520 case NORMAL: { 1521 case NORMAL:
1521 if (receiver->IsGlobalObject()) { 1522 if (receiver->IsGlobalObject()) {
1522 // The stub generated for the global object picks the value directly 1523 // The stub generated for the global object picks the value directly
1523 // from the property cell. So the property must be directly on the 1524 // from the property cell. So the property must be directly on the
1524 // global object. 1525 // global object.
1525 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1526 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1526 JSGlobalPropertyCell* cell = 1527 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
1527 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 1528 code = isolate()->stub_cache()->ComputeStoreGlobal(
1528 maybe_code = isolate()->stub_cache()->ComputeStoreGlobal( 1529 name, global, cell, strict_mode);
1529 *name, *global, cell, strict_mode);
1530 } else { 1530 } else {
1531 if (lookup->holder() != *receiver) return; 1531 if (lookup->holder() != *receiver) return;
1532 maybe_code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode); 1532 code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
1533 } 1533 }
1534 break; 1534 break;
1535 }
1536 case CALLBACKS: { 1535 case CALLBACKS: {
1537 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; 1536 Handle<Object> callback_object(lookup->GetCallbackObject());
1538 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1537 if (!callback_object->IsAccessorInfo()) return;
1538 Handle<AccessorInfo> callback =
1539 Handle<AccessorInfo>::cast(callback_object);
1539 if (v8::ToCData<Address>(callback->setter()) == 0) return; 1540 if (v8::ToCData<Address>(callback->setter()) == 0) return;
1540 maybe_code = isolate()->stub_cache()->ComputeStoreCallback( 1541 code = isolate()->stub_cache()->ComputeStoreCallback(
1541 *name, *receiver, callback, strict_mode); 1542 name, receiver, callback, strict_mode);
1542 break; 1543 break;
1543 } 1544 }
1544 case INTERCEPTOR: { 1545 case INTERCEPTOR:
1545 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); 1546 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
1546 maybe_code = isolate()->stub_cache()->ComputeStoreInterceptor( 1547 code = isolate()->stub_cache()->ComputeStoreInterceptor(
1547 *name, *receiver, strict_mode); 1548 name, receiver, strict_mode);
1548 break; 1549 break;
1549 }
1550 default: 1550 default:
1551 return; 1551 return;
1552 } 1552 }
1553 1553
1554 // If we're unable to compute the stub (not enough memory left), we
1555 // simply avoid updating the caches.
1556 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
1557
1558 // Patch the call site depending on the state of the cache. 1554 // Patch the call site depending on the state of the cache.
1559 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { 1555 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1560 set_target(Code::cast(code)); 1556 set_target(*code);
1561 } else if (state == MONOMORPHIC) { 1557 } else if (state == MONOMORPHIC) {
1562 // Only move to megamorphic if the target changes. 1558 // Only move to megamorphic if the target changes.
1563 if (target() != Code::cast(code)) { 1559 if (target() != *code) {
1564 set_target((strict_mode == kStrictMode) 1560 set_target((strict_mode == kStrictMode)
1565 ? megamorphic_stub_strict() 1561 ? megamorphic_stub_strict()
1566 : megamorphic_stub()); 1562 : megamorphic_stub());
1567 } 1563 }
1568 } else if (state == MEGAMORPHIC) { 1564 } else if (state == MEGAMORPHIC) {
1569 // Update the stub cache. 1565 // Update the stub cache.
1570 isolate()->stub_cache()->Set(*name, 1566 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1571 receiver->map(),
1572 Code::cast(code));
1573 } 1567 }
1574 1568
1575 #ifdef DEBUG 1569 #ifdef DEBUG
1576 TraceIC("StoreIC", name, state, target()); 1570 TraceIC("StoreIC", name, state, target());
1577 #endif 1571 #endif
1578 } 1572 }
1579 1573
1580 1574
1581 static bool AddOneReceiverMapIfMissing(MapList* receiver_maps, 1575 static bool AddOneReceiverMapIfMissing(MapList* receiver_maps,
1582 Map* new_receiver_map) { 1576 Map* new_receiver_map) {
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
2083 NoHandleAllocation na; 2077 NoHandleAllocation na;
2084 ASSERT(args.length() == 2); 2078 ASSERT(args.length() == 2);
2085 KeyedLoadIC ic(isolate); 2079 KeyedLoadIC ic(isolate);
2086 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 2080 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2087 return ic.Load(state, args.at<Object>(0), args.at<Object>(1), true); 2081 return ic.Load(state, args.at<Object>(0), args.at<Object>(1), true);
2088 } 2082 }
2089 2083
2090 2084
2091 // Used from ic-<arch>.cc. 2085 // Used from ic-<arch>.cc.
2092 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { 2086 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
2093 NoHandleAllocation na; 2087 HandleScope scope;
2094 ASSERT(args.length() == 3); 2088 ASSERT(args.length() == 3);
2095 StoreIC ic(isolate); 2089 StoreIC ic(isolate);
2096 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 2090 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2097 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 2091 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
2098 return ic.Store(state, 2092 return ic.Store(state,
2099 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), 2093 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode),
2100 args.at<Object>(0), 2094 args.at<Object>(0),
2101 args.at<String>(1), 2095 args.at<String>(1),
2102 args.at<Object>(2)); 2096 args.at<Object>(2));
2103 } 2097 }
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2621 #undef ADDR 2615 #undef ADDR
2622 }; 2616 };
2623 2617
2624 2618
2625 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2619 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2626 return IC_utilities[id]; 2620 return IC_utilities[id];
2627 } 2621 }
2628 2622
2629 2623
2630 } } // namespace v8::internal 2624 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698