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

Side by Side Diff: src/ic.cc

Issue 142893003: Merge bleeding_edge 18658:18677 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 11 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/mips/full-codegen-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 // 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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 if (proto->IsNull()) { 224 if (proto->IsNull()) {
225 ASSERT(!lookup->IsFound()); 225 ASSERT(!lookup->IsFound());
226 return; 226 return;
227 } 227 }
228 228
229 object = proto; 229 object = proto;
230 } 230 }
231 } 231 }
232 232
233 233
234 bool CallIC::TryUpdateExtraICState(LookupResult* lookup,
235 Handle<Object> object) {
236 if (!lookup->IsConstantFunction()) return false;
237 JSFunction* function = lookup->GetConstantFunction();
238 if (!function->shared()->HasBuiltinFunctionId()) return false;
239
240 // Fetch the arguments passed to the called function.
241 const int argc = target()->arguments_count();
242 Address entry = isolate()->c_entry_fp(isolate()->thread_local_top());
243 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
244 Arguments args(argc + 1,
245 &Memory::Object_at(fp +
246 StandardFrameConstants::kCallerSPOffset +
247 argc * kPointerSize));
248 switch (function->shared()->builtin_function_id()) {
249 case kStringCharCodeAt:
250 case kStringCharAt:
251 if (object->IsString()) {
252 String* string = String::cast(*object);
253 // Check there's the right string value or wrapper in the receiver slot.
254 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value());
255 // If we're in the default (fastest) state and the index is
256 // out of bounds, update the state to record this fact.
257 if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB &&
258 argc >= 1 && args[1]->IsNumber()) {
259 double index = DoubleToInteger(args.number_at(1));
260 if (index < 0 || index >= string->length()) {
261 set_extra_ic_state(StringStubState::update(extra_ic_state(),
262 STRING_INDEX_OUT_OF_BOUNDS));
263 return true;
264 }
265 }
266 }
267 break;
268 default:
269 return false;
270 }
271 return false;
272 }
273
274
275 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 234 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
276 Handle<String> name) { 235 Handle<String> name) {
277 if (target()->is_call_stub()) {
278 LookupResult lookup(isolate());
279 LookupForRead(receiver, name, &lookup);
280 if (static_cast<CallIC*>(this)->TryUpdateExtraICState(&lookup, receiver)) {
281 return true;
282 }
283 }
284
285 if (target()->is_keyed_stub()) { 236 if (target()->is_keyed_stub()) {
286 // Determine whether the failure is due to a name failure. 237 // Determine whether the failure is due to a name failure.
287 if (!name->IsName()) return false; 238 if (!name->IsName()) return false;
288 Name* stub_name = target()->FindFirstName(); 239 Name* stub_name = target()->FindFirstName();
289 if (*name != stub_name) return false; 240 if (*name != stub_name) return false;
290 } 241 }
291 242
292 InlineCacheHolderFlag cache_holder = 243 InlineCacheHolderFlag cache_holder =
293 Code::ExtractCacheHolderFromFlags(target()->flags()); 244 Code::ExtractCacheHolderFromFlags(target()->flags());
294 245
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 // Otherwise, it will fail in the lookup step. 570 // Otherwise, it will fail in the lookup step.
620 } 571 }
621 572
622 // Lookup the property in the object. 573 // Lookup the property in the object.
623 LookupResult lookup(isolate()); 574 LookupResult lookup(isolate());
624 LookupForRead(object, name, &lookup); 575 LookupForRead(object, name, &lookup);
625 576
626 if (!lookup.IsFound()) { 577 if (!lookup.IsFound()) {
627 // If the object does not have the requested property, check which 578 // If the object does not have the requested property, check which
628 // exception we need to throw. 579 // exception we need to throw.
629 return IsUndeclaredGlobal(object) 580 return object->IsGlobalObject()
630 ? ReferenceError("not_defined", name) 581 ? ReferenceError("not_defined", name)
631 : TypeError("undefined_method", object, name); 582 : TypeError("undefined_method", object, name);
632 } 583 }
633 584
634 // Lookup is valid: Update inline cache and stub cache. 585 // Lookup is valid: Update inline cache and stub cache.
635 if (use_ic) UpdateCaches(&lookup, object, name); 586 if (use_ic) UpdateCaches(&lookup, object, name);
636 587
637 // Get the property. 588 // Get the property.
638 PropertyAttributes attr; 589 PropertyAttributes attr;
639 Handle<Object> result = 590 Handle<Object> result =
640 Object::GetProperty(object, object, &lookup, name, &attr); 591 Object::GetProperty(object, object, &lookup, name, &attr);
641 RETURN_IF_EMPTY_HANDLE(isolate(), result); 592 RETURN_IF_EMPTY_HANDLE(isolate(), result);
642 593
643 if (lookup.IsInterceptor() && attr == ABSENT) { 594 if (lookup.IsInterceptor() && attr == ABSENT) {
644 // If the object does not have the requested property, check which 595 // If the object does not have the requested property, check which
645 // exception we need to throw. 596 // exception we need to throw.
646 return IsUndeclaredGlobal(object) 597 return object->IsGlobalObject()
647 ? ReferenceError("not_defined", name) 598 ? ReferenceError("not_defined", name)
648 : TypeError("undefined_method", object, name); 599 : TypeError("undefined_method", object, name);
649 } 600 }
650 601
651 ASSERT(!result->IsTheHole()); 602 ASSERT(!result->IsTheHole());
652 603
653 // Make receiver an object if the callee requires it. Strict mode or builtin 604 // Make receiver an object if the callee requires it. Strict mode or builtin
654 // functions do not wrap the receiver, non-strict functions and objects 605 // functions do not wrap the receiver, non-strict functions and objects
655 // called as functions do. 606 // called as functions do.
656 ReceiverToObjectIfRequired(result, object); 607 ReceiverToObjectIfRequired(result, object);
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 break; 1046 break;
1096 case GENERIC: 1047 case GENERIC:
1097 UNREACHABLE(); 1048 UNREACHABLE();
1098 break; 1049 break;
1099 } 1050 }
1100 } 1051 }
1101 1052
1102 1053
1103 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) { 1054 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) {
1104 Handle<Code> ic = isolate->stub_cache()->ComputeLoad( 1055 Handle<Code> ic = isolate->stub_cache()->ComputeLoad(
1105 UNINITIALIZED, IC::ComputeExtraICState(mode)); 1056 UNINITIALIZED, ComputeExtraICState(mode));
1106 return ic; 1057 return ic;
1107 } 1058 }
1108 1059
1109 1060
1110 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, 1061 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
1111 ContextualMode mode) { 1062 ContextualMode mode) {
1112 return isolate->stub_cache()->ComputeLoad( 1063 return isolate->stub_cache()->ComputeLoad(
1113 PREMONOMORPHIC, IC::ComputeExtraICState(mode)); 1064 PREMONOMORPHIC, ComputeExtraICState(mode));
1114 } 1065 }
1115 1066
1116 1067
1117 Handle<Code> LoadIC::megamorphic_stub() { 1068 Handle<Code> LoadIC::megamorphic_stub() {
1118 return isolate()->stub_cache()->ComputeLoad( 1069 return isolate()->stub_cache()->ComputeLoad(
1119 MEGAMORPHIC, extra_ic_state()); 1070 MEGAMORPHIC, extra_ic_state());
1120 } 1071 }
1121 1072
1122 1073
1123 Handle<Code> LoadIC::SimpleFieldLoad(int offset, 1074 Handle<Code> LoadIC::SimpleFieldLoad(int offset,
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 receiver, name, value, NONE, strict_mode(), store_mode); 1514 receiver, name, value, NONE, strict_mode(), store_mode);
1564 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1515 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1565 return *result; 1516 return *result;
1566 } 1517 }
1567 1518
1568 LookupResult lookup(isolate()); 1519 LookupResult lookup(isolate());
1569 bool can_store = LookupForWrite(receiver, name, value, &lookup, this); 1520 bool can_store = LookupForWrite(receiver, name, value, &lookup, this);
1570 if (!can_store && 1521 if (!can_store &&
1571 strict_mode() == kStrictMode && 1522 strict_mode() == kStrictMode &&
1572 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1523 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1573 IsUndeclaredGlobal(object)) { 1524 object->IsGlobalObject()) {
1574 // Strict mode doesn't allow setting non-existent global property. 1525 // Strict mode doesn't allow setting non-existent global property.
1575 return ReferenceError("not_defined", name); 1526 return ReferenceError("not_defined", name);
1576 } 1527 }
1577 if (FLAG_use_ic) { 1528 if (FLAG_use_ic) {
1578 if (state() == UNINITIALIZED) { 1529 if (state() == UNINITIALIZED) {
1579 Handle<Code> stub = pre_monomorphic_stub(); 1530 Handle<Code> stub = pre_monomorphic_stub();
1580 set_target(*stub); 1531 set_target(*stub);
1581 TRACE_IC("StoreIC", name); 1532 TRACE_IC("StoreIC", name);
1582 } else if (can_store) { 1533 } else if (can_store) {
1583 UpdateCaches(&lookup, receiver, name, value); 1534 UpdateCaches(&lookup, receiver, name, value);
1584 } else if (!name->IsCacheable(isolate()) || 1535 } else if (!name->IsCacheable(isolate()) ||
1585 lookup.IsNormal() || 1536 lookup.IsNormal() ||
1586 (lookup.IsField() && lookup.CanHoldValue(value))) { 1537 (lookup.IsField() && lookup.CanHoldValue(value))) {
1587 Handle<Code> stub = generic_stub(); 1538 Handle<Code> stub = generic_stub();
1588 set_target(*stub); 1539 set_target(*stub);
1589 } 1540 }
1590 } 1541 }
1591 1542
1592 // Set the property. 1543 // Set the property.
1593 Handle<Object> result = JSReceiver::SetProperty( 1544 Handle<Object> result = JSReceiver::SetProperty(
1594 receiver, name, value, NONE, strict_mode(), store_mode); 1545 receiver, name, value, NONE, strict_mode(), store_mode);
1595 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1546 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1596 return *result; 1547 return *result;
1597 } 1548 }
1598 1549
1599 1550
1600 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, 1551 Handle<Code> StoreIC::initialize_stub(Isolate* isolate,
1601 StrictModeFlag strict_mode, 1552 StrictModeFlag strict_mode) {
1602 ContextualMode mode) { 1553 ExtraICState extra_state = ComputeExtraICState(strict_mode);
1603 ExtraICState extra_state = ComputeExtraICState(strict_mode, mode);
1604 Handle<Code> ic = isolate->stub_cache()->ComputeStore( 1554 Handle<Code> ic = isolate->stub_cache()->ComputeStore(
1605 UNINITIALIZED, extra_state); 1555 UNINITIALIZED, extra_state);
1606 return ic; 1556 return ic;
1607 } 1557 }
1608 1558
1609 1559
1610 Handle<Code> StoreIC::megamorphic_stub() { 1560 Handle<Code> StoreIC::megamorphic_stub() {
1611 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state()); 1561 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state());
1612 } 1562 }
1613 1563
1614 1564
1615 Handle<Code> StoreIC::generic_stub() const { 1565 Handle<Code> StoreIC::generic_stub() const {
1616 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state()); 1566 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state());
1617 } 1567 }
1618 1568
1619 1569
1620 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, 1570 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate,
1621 StrictModeFlag strict_mode, 1571 StrictModeFlag strict_mode) {
1622 ContextualMode contextual_mode) { 1572 ExtraICState state = ComputeExtraICState(strict_mode);
1623 ExtraICState state = StoreIC::ComputeExtraICState(strict_mode,
1624 contextual_mode);
1625 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state); 1573 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state);
1626 } 1574 }
1627 1575
1628 1576
1629 void StoreIC::UpdateCaches(LookupResult* lookup, 1577 void StoreIC::UpdateCaches(LookupResult* lookup,
1630 Handle<JSObject> receiver, 1578 Handle<JSObject> receiver,
1631 Handle<String> name, 1579 Handle<String> name,
1632 Handle<Object> value) { 1580 Handle<Object> value) {
1633 ASSERT(lookup->IsFound()); 1581 ASSERT(lookup->IsFound());
1634 1582
(...skipping 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after
3221 #undef ADDR 3169 #undef ADDR
3222 }; 3170 };
3223 3171
3224 3172
3225 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3173 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3226 return IC_utilities[id]; 3174 return IC_utilities[id];
3227 } 3175 }
3228 3176
3229 3177
3230 } } // namespace v8::internal 3178 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698