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

Side by Side Diff: src/ic.cc

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 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 | « src/ic.h ('k') | src/ic-inl.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 // Reset the map check of the inlined inobject property store (if 342 // Reset the map check of the inlined inobject property store (if
343 // present) to guarantee failure by holding an invalid map (the null 343 // present) to guarantee failure by holding an invalid map (the null
344 // value). The offset can be patched to anything. 344 // value). The offset can be patched to anything.
345 PatchInlinedStore(address, HEAP->null_value(), 0); 345 PatchInlinedStore(address, HEAP->null_value(), 0);
346 } 346 }
347 347
348 348
349 void StoreIC::Clear(Address address, Code* target) { 349 void StoreIC::Clear(Address address, Code* target) {
350 if (target->ic_state() == UNINITIALIZED) return; 350 if (target->ic_state() == UNINITIALIZED) return;
351 ClearInlinedVersion(address); 351 ClearInlinedVersion(address);
352 SetTargetAtAddress(address, initialize_stub()); 352 SetTargetAtAddress(address,
353 (target->extra_ic_state() == kStrictMode)
354 ? initialize_stub_strict()
355 : initialize_stub());
353 } 356 }
354 357
355 358
356 void KeyedStoreIC::ClearInlinedVersion(Address address) { 359 void KeyedStoreIC::ClearInlinedVersion(Address address) {
357 // Insert null as the elements map to check for. This will make 360 // Insert null as the elements map to check for. This will make
358 // sure that the elements fast-case map check fails so that control 361 // sure that the elements fast-case map check fails so that control
359 // flows to the IC instead of the inlined version. 362 // flows to the IC instead of the inlined version.
360 PatchInlinedStore(address, HEAP->null_value()); 363 PatchInlinedStore(address, HEAP->null_value());
361 } 364 }
362 365
363 366
364 void KeyedStoreIC::RestoreInlinedVersion(Address address) { 367 void KeyedStoreIC::RestoreInlinedVersion(Address address) {
365 // Restore the fast-case elements map check so that the inlined 368 // Restore the fast-case elements map check so that the inlined
366 // version can be used again. 369 // version can be used again.
367 PatchInlinedStore(address, HEAP->fixed_array_map()); 370 PatchInlinedStore(address, HEAP->fixed_array_map());
368 } 371 }
369 372
370 373
371 void KeyedStoreIC::Clear(Address address, Code* target) { 374 void KeyedStoreIC::Clear(Address address, Code* target) {
372 if (target->ic_state() == UNINITIALIZED) return; 375 if (target->ic_state() == UNINITIALIZED) return;
373 SetTargetAtAddress(address, initialize_stub()); 376 SetTargetAtAddress(address,
377 (target->extra_ic_state() == kStrictMode)
378 ? initialize_stub_strict()
379 : initialize_stub());
374 } 380 }
375 381
376 382
377 static bool HasInterceptorGetter(JSObject* object) { 383 static bool HasInterceptorGetter(JSObject* object) {
378 return !object->GetNamedInterceptor()->getter()->IsUndefined(); 384 return !object->GetNamedInterceptor()->getter()->IsUndefined();
379 } 385 }
380 386
381 387
382 static void LookupForRead(Object* object, 388 static void LookupForRead(Object* object,
383 String* name, 389 String* name,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 StackFrameLocator locator; 438 StackFrameLocator locator;
433 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 439 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
434 int index = frame->ComputeExpressionsCount() - (argc + 1); 440 int index = frame->ComputeExpressionsCount() - (argc + 1);
435 frame->SetExpression(index, *target); 441 frame->SetExpression(index, *target);
436 } 442 }
437 443
438 return *delegate; 444 return *delegate;
439 } 445 }
440 446
441 447
442 void CallICBase::ReceiverToObject(Handle<Object> object) { 448 void CallICBase::ReceiverToObjectIfRequired(Handle<Object> callee,
443 HandleScope scope(isolate()); 449 Handle<Object> object) {
444 Handle<Object> receiver = object; 450 if (callee->IsJSFunction()) {
451 Handle<JSFunction> function = Handle<JSFunction>::cast(callee);
452 if (function->shared()->strict_mode() || function->IsBuiltin()) {
453 // Do not wrap receiver for strict mode functions or for builtins.
454 return;
455 }
456 }
445 457
446 // Change the receiver to the result of calling ToObject on it. 458 // And only wrap string, number or boolean.
447 const int argc = this->target()->arguments_count(); 459 if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
448 StackFrameLocator locator; 460 // Change the receiver to the result of calling ToObject on it.
449 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 461 const int argc = this->target()->arguments_count();
450 int index = frame->ComputeExpressionsCount() - (argc + 1); 462 StackFrameLocator locator;
451 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); 463 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
464 int index = frame->ComputeExpressionsCount() - (argc + 1);
465 frame->SetExpression(index, *isolate()->factory()->ToObject(object));
466 }
452 } 467 }
453 468
454 469
455 MaybeObject* CallICBase::LoadFunction(State state, 470 MaybeObject* CallICBase::LoadFunction(State state,
456 Code::ExtraICState extra_ic_state, 471 Code::ExtraICState extra_ic_state,
457 Handle<Object> object, 472 Handle<Object> object,
458 Handle<String> name) { 473 Handle<String> name) {
459 // If the object is undefined or null it's illegal to try to get any 474 // If the object is undefined or null it's illegal to try to get any
460 // of its properties; throw a TypeError in that case. 475 // of its properties; throw a TypeError in that case.
461 if (object->IsUndefined() || object->IsNull()) { 476 if (object->IsUndefined() || object->IsNull()) {
462 return TypeError("non_object_property_call", object, name); 477 return TypeError("non_object_property_call", object, name);
463 } 478 }
464 479
465 if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
466 ReceiverToObject(object);
467 }
468
469 // Check if the name is trivially convertible to an index and get 480 // Check if the name is trivially convertible to an index and get
470 // the element if so. 481 // the element if so.
471 uint32_t index; 482 uint32_t index;
472 if (name->AsArrayIndex(&index)) { 483 if (name->AsArrayIndex(&index)) {
473 Object* result; 484 Object* result;
474 { MaybeObject* maybe_result = object->GetElement(index); 485 { MaybeObject* maybe_result = object->GetElement(index);
475 if (!maybe_result->ToObject(&result)) return maybe_result; 486 if (!maybe_result->ToObject(&result)) return maybe_result;
476 } 487 }
477 488
478 if (result->IsJSFunction()) return result; 489 if (result->IsJSFunction()) return result;
(...skipping 23 matching lines...) Expand all
502 UpdateCaches(&lookup, state, extra_ic_state, object, name); 513 UpdateCaches(&lookup, state, extra_ic_state, object, name);
503 } 514 }
504 515
505 // Get the property. 516 // Get the property.
506 PropertyAttributes attr; 517 PropertyAttributes attr;
507 Object* result; 518 Object* result;
508 { MaybeObject* maybe_result = 519 { MaybeObject* maybe_result =
509 object->GetProperty(*object, &lookup, *name, &attr); 520 object->GetProperty(*object, &lookup, *name, &attr);
510 if (!maybe_result->ToObject(&result)) return maybe_result; 521 if (!maybe_result->ToObject(&result)) return maybe_result;
511 } 522 }
523
512 if (lookup.type() == INTERCEPTOR) { 524 if (lookup.type() == INTERCEPTOR) {
513 // If the object does not have the requested property, check which 525 // If the object does not have the requested property, check which
514 // exception we need to throw. 526 // exception we need to throw.
515 if (attr == ABSENT) { 527 if (attr == ABSENT) {
516 if (IsContextual(object)) { 528 if (IsContextual(object)) {
517 return ReferenceError("not_defined", name); 529 return ReferenceError("not_defined", name);
518 } 530 }
519 return TypeError("undefined_method", object, name); 531 return TypeError("undefined_method", object, name);
520 } 532 }
521 } 533 }
522 534
523 ASSERT(result != isolate()->heap()->the_hole_value()); 535 ASSERT(!result->IsTheHole());
524 536
525 if (result->IsJSFunction()) { 537 HandleScope scope(isolate());
538 // Wrap result in a handle because ReceiverToObjectIfRequired may allocate
539 // new object and cause GC.
540 Handle<Object> result_handle(result);
541 // Make receiver an object if the callee requires it. Strict mode or builtin
542 // functions do not wrap the receiver, non-strict functions and objects
543 // called as functions do.
544 ReceiverToObjectIfRequired(result_handle, object);
545
546 if (result_handle->IsJSFunction()) {
526 #ifdef ENABLE_DEBUGGER_SUPPORT 547 #ifdef ENABLE_DEBUGGER_SUPPORT
527 // Handle stepping into a function if step into is active. 548 // Handle stepping into a function if step into is active.
528 Debug* debug = isolate()->debug(); 549 Debug* debug = isolate()->debug();
529 if (debug->StepInActive()) { 550 if (debug->StepInActive()) {
530 // Protect the result in a handle as the debugger can allocate and might 551 // Protect the result in a handle as the debugger can allocate and might
531 // cause GC. 552 // cause GC.
532 HandleScope scope(isolate()); 553 Handle<JSFunction> function(JSFunction::cast(*result_handle), isolate());
533 Handle<JSFunction> function(JSFunction::cast(result), isolate());
534 debug->HandleStepIn(function, object, fp(), false); 554 debug->HandleStepIn(function, object, fp(), false);
535 return *function; 555 return *function;
536 } 556 }
537 #endif 557 #endif
538 558
539 return result; 559 return *result_handle;
540 } 560 }
541 561
542 // Try to find a suitable function delegate for the object at hand. 562 // Try to find a suitable function delegate for the object at hand.
543 result = TryCallAsFunction(result); 563 result_handle = Handle<Object>(TryCallAsFunction(*result_handle));
544 MaybeObject* answer = result; 564 if (result_handle->IsJSFunction()) return *result_handle;
545 if (!result->IsJSFunction()) { 565
546 answer = TypeError("property_not_function", object, name); 566 return TypeError("property_not_function", object, name);
547 }
548 return answer;
549 } 567 }
550 568
551 569
552 bool CallICBase::TryUpdateExtraICState(LookupResult* lookup, 570 bool CallICBase::TryUpdateExtraICState(LookupResult* lookup,
553 Handle<Object> object, 571 Handle<Object> object,
554 Code::ExtraICState* extra_ic_state) { 572 Code::ExtraICState* extra_ic_state) {
555 ASSERT(kind_ == Code::CALL_IC); 573 ASSERT(kind_ == Code::CALL_IC);
556 if (lookup->type() != CONSTANT_FUNCTION) return false; 574 if (lookup->type() != CONSTANT_FUNCTION) return false;
557 JSFunction* function = lookup->GetConstantFunction(); 575 JSFunction* function = lookup->GetConstantFunction();
558 if (!function->shared()->HasBuiltinFunctionId()) return false; 576 if (!function->shared()->HasBuiltinFunctionId()) return false;
559 577
560 // Fetch the arguments passed to the called function. 578 // Fetch the arguments passed to the called function.
561 const int argc = target()->arguments_count(); 579 const int argc = target()->arguments_count();
562 Address entry = isolate()->c_entry_fp(isolate()->thread_local_top()); 580 Address entry = isolate()->c_entry_fp(isolate()->thread_local_top());
563 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 581 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
564 Arguments args(argc + 1, 582 Arguments args(argc + 1,
565 &Memory::Object_at(fp + 583 &Memory::Object_at(fp +
566 StandardFrameConstants::kCallerSPOffset + 584 StandardFrameConstants::kCallerSPOffset +
567 argc * kPointerSize)); 585 argc * kPointerSize));
568 switch (function->shared()->builtin_function_id()) { 586 switch (function->shared()->builtin_function_id()) {
569 case kStringCharCodeAt: 587 case kStringCharCodeAt:
570 case kStringCharAt: 588 case kStringCharAt:
571 if (object->IsString()) { 589 if (object->IsString()) {
572 String* string = String::cast(*object); 590 String* string = String::cast(*object);
573 // Check that there's the right wrapper in the receiver slot. 591 // Check there's the right string value or wrapper in the receiver slot.
574 ASSERT(string == JSValue::cast(args[0])->value()); 592 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value());
575 // If we're in the default (fastest) state and the index is 593 // If we're in the default (fastest) state and the index is
576 // out of bounds, update the state to record this fact. 594 // out of bounds, update the state to record this fact.
577 if (*extra_ic_state == DEFAULT_STRING_STUB && 595 if (*extra_ic_state == DEFAULT_STRING_STUB &&
578 argc >= 1 && args[1]->IsNumber()) { 596 argc >= 1 && args[1]->IsNumber()) {
579 double index; 597 double index;
580 if (args[1]->IsSmi()) { 598 if (args[1]->IsSmi()) {
581 index = Smi::cast(args[1])->value(); 599 index = Smi::cast(args[1])->value();
582 } else { 600 } else {
583 ASSERT(args[1]->IsHeapNumber()); 601 ASSERT(args[1]->IsHeapNumber());
584 index = DoubleToInteger(HeapNumber::cast(args[1])->value()); 602 index = DoubleToInteger(HeapNumber::cast(args[1])->value());
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 return CallICBase::LoadFunction(state, 798 return CallICBase::LoadFunction(state,
781 Code::kNoExtraICState, 799 Code::kNoExtraICState,
782 object, 800 object,
783 Handle<String>::cast(key)); 801 Handle<String>::cast(key));
784 } 802 }
785 803
786 if (object->IsUndefined() || object->IsNull()) { 804 if (object->IsUndefined() || object->IsNull()) {
787 return TypeError("non_object_property_call", object, key); 805 return TypeError("non_object_property_call", object, key);
788 } 806 }
789 807
790 if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
791 ReceiverToObject(object);
792 }
793
794 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) { 808 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) {
795 int argc = target()->arguments_count(); 809 int argc = target()->arguments_count();
796 InLoopFlag in_loop = target()->ic_in_loop(); 810 InLoopFlag in_loop = target()->ic_in_loop();
797 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( 811 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
798 argc, in_loop, Code::KEYED_CALL_IC); 812 argc, in_loop, Code::KEYED_CALL_IC);
799 Object* code; 813 Object* code;
800 if (maybe_code->ToObject(&code)) { 814 if (maybe_code->ToObject(&code)) {
801 set_target(Code::cast(code)); 815 set_target(Code::cast(code));
802 #ifdef DEBUG 816 #ifdef DEBUG
803 TraceIC( 817 TraceIC(
804 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); 818 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
805 #endif 819 #endif
806 } 820 }
807 } 821 }
808 Object* result; 822
809 { MaybeObject* maybe_result = Runtime::GetObjectProperty(isolate(), 823 HandleScope scope(isolate());
810 object, 824 Handle<Object> result = GetProperty(object, key);
811 key); 825 RETURN_IF_EMPTY_HANDLE(isolate(), result);
812 if (!maybe_result->ToObject(&result)) return maybe_result; 826
813 } 827 // Make receiver an object if the callee requires it. Strict mode or builtin
814 if (result->IsJSFunction()) return result; 828 // functions do not wrap the receiver, non-strict functions and objects
815 result = TryCallAsFunction(result); 829 // called as functions do.
816 MaybeObject* answer = result; 830 ReceiverToObjectIfRequired(result, object);
817 if (!result->IsJSFunction()) { 831
818 answer = TypeError("property_not_function", object, key); 832 if (result->IsJSFunction()) return *result;
819 } 833 result = Handle<Object>(TryCallAsFunction(*result));
820 return answer; 834 if (result->IsJSFunction()) return *result;
835
836 return TypeError("property_not_function", object, key);
821 } 837 }
822 838
823 839
824 #ifdef DEBUG 840 #ifdef DEBUG
825 #define TRACE_IC_NAMED(msg, name) \ 841 #define TRACE_IC_NAMED(msg, name) \
826 if (FLAG_trace_ic) PrintF(msg, *(name)->ToCString()) 842 if (FLAG_trace_ic) PrintF(msg, *(name)->ToCString())
827 #else 843 #else
828 #define TRACE_IC_NAMED(msg, name) 844 #define TRACE_IC_NAMED(msg, name)
829 #endif 845 #endif
830 846
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 if (use_ic) { 1255 if (use_ic) {
1240 Code* stub = generic_stub(); 1256 Code* stub = generic_stub();
1241 if (state == UNINITIALIZED) { 1257 if (state == UNINITIALIZED) {
1242 if (object->IsString() && key->IsNumber()) { 1258 if (object->IsString() && key->IsNumber()) {
1243 stub = string_stub(); 1259 stub = string_stub();
1244 } else if (object->IsJSObject()) { 1260 } else if (object->IsJSObject()) {
1245 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1261 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1246 if (receiver->HasExternalArrayElements()) { 1262 if (receiver->HasExternalArrayElements()) {
1247 MaybeObject* probe = 1263 MaybeObject* probe =
1248 isolate()->stub_cache()->ComputeKeyedLoadOrStoreExternalArray( 1264 isolate()->stub_cache()->ComputeKeyedLoadOrStoreExternalArray(
1249 *receiver, false); 1265 *receiver, false, kNonStrictMode);
1250 stub = probe->IsFailure() ? 1266 stub = probe->IsFailure() ?
1251 NULL : Code::cast(probe->ToObjectUnchecked()); 1267 NULL : Code::cast(probe->ToObjectUnchecked());
1252 } else if (receiver->HasIndexedInterceptor()) { 1268 } else if (receiver->HasIndexedInterceptor()) {
1253 stub = indexed_interceptor_stub(); 1269 stub = indexed_interceptor_stub();
1254 } else if (receiver->HasPixelElements()) { 1270 } else if (receiver->HasPixelElements()) {
1255 MaybeObject* probe = 1271 MaybeObject* probe =
1256 isolate()->stub_cache()->ComputeKeyedLoadPixelArray(*receiver); 1272 isolate()->stub_cache()->ComputeKeyedLoadPixelArray(*receiver);
1257 stub = probe->IsFailure() ? 1273 stub = probe->IsFailure() ?
1258 NULL : Code::cast(probe->ToObjectUnchecked()); 1274 NULL : Code::cast(probe->ToObjectUnchecked());
1259 } else if (key->IsSmi() && 1275 } else if (key->IsSmi() &&
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 object->LocalLookupRealNamedProperty(name, lookup); 1406 object->LocalLookupRealNamedProperty(name, lookup);
1391 return StoreICableLookup(lookup); 1407 return StoreICableLookup(lookup);
1392 } 1408 }
1393 } 1409 }
1394 1410
1395 return true; 1411 return true;
1396 } 1412 }
1397 1413
1398 1414
1399 MaybeObject* StoreIC::Store(State state, 1415 MaybeObject* StoreIC::Store(State state,
1416 StrictModeFlag strict_mode,
1400 Handle<Object> object, 1417 Handle<Object> object,
1401 Handle<String> name, 1418 Handle<String> name,
1402 Handle<Object> value) { 1419 Handle<Object> value) {
1403 // If the object is undefined or null it's illegal to try to set any 1420 // If the object is undefined or null it's illegal to try to set any
1404 // properties on it; throw a TypeError in that case. 1421 // properties on it; throw a TypeError in that case.
1405 if (object->IsUndefined() || object->IsNull()) { 1422 if (object->IsUndefined() || object->IsNull()) {
1406 return TypeError("non_object_property_store", object, name); 1423 return TypeError("non_object_property_store", object, name);
1407 } 1424 }
1408 1425
1409 // Ignore stores where the receiver is not a JSObject. 1426 // Ignore stores where the receiver is not a JSObject.
1410 if (!object->IsJSObject()) return *value; 1427 if (!object->IsJSObject()) return *value;
1411 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1428 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1412 1429
1413 // Check if the given name is an array index. 1430 // Check if the given name is an array index.
1414 uint32_t index; 1431 uint32_t index;
1415 if (name->AsArrayIndex(&index)) { 1432 if (name->AsArrayIndex(&index)) {
1416 HandleScope scope(isolate()); 1433 HandleScope scope(isolate());
1417 Handle<Object> result = SetElement(receiver, index, value); 1434 Handle<Object> result = SetElement(receiver, index, value);
1418 if (result.is_null()) return Failure::Exception(); 1435 if (result.is_null()) return Failure::Exception();
1419 return *value; 1436 return *value;
1420 } 1437 }
1421 1438
1422 // Use specialized code for setting the length of arrays. 1439 // Use specialized code for setting the length of arrays.
1423 if (receiver->IsJSArray() 1440 if (receiver->IsJSArray()
1424 && name->Equals(isolate()->heap()->length_symbol()) 1441 && name->Equals(isolate()->heap()->length_symbol())
1425 && receiver->AllowsSetElementsLength()) { 1442 && receiver->AllowsSetElementsLength()) {
1426 #ifdef DEBUG 1443 #ifdef DEBUG
1427 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); 1444 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
1428 #endif 1445 #endif
1429 Code* target = isolate()->builtins()->builtin( 1446 Builtins::Name target = (strict_mode == kStrictMode)
1430 Builtins::StoreIC_ArrayLength); 1447 ? Builtins::StoreIC_ArrayLength_Strict
1431 set_target(target); 1448 : Builtins::StoreIC_ArrayLength;
1432 return receiver->SetProperty(*name, *value, NONE); 1449 set_target(isolate()->builtins()->builtin(target));
1450 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1433 } 1451 }
1434 1452
1435 // Lookup the property locally in the receiver. 1453 // Lookup the property locally in the receiver.
1436 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { 1454 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1437 LookupResult lookup; 1455 LookupResult lookup;
1438 1456
1439 if (LookupForWrite(*receiver, *name, &lookup)) { 1457 if (LookupForWrite(*receiver, *name, &lookup)) {
1440 bool can_be_inlined = 1458 bool can_be_inlined =
1441 state == UNINITIALIZED && 1459 state == UNINITIALIZED &&
1442 lookup.IsProperty() && 1460 lookup.IsProperty() &&
1443 lookup.holder() == *receiver && 1461 lookup.holder() == *receiver &&
1444 lookup.type() == FIELD && 1462 lookup.type() == FIELD &&
1445 !receiver->IsAccessCheckNeeded(); 1463 !receiver->IsAccessCheckNeeded();
1446 1464
1447 if (can_be_inlined) { 1465 if (can_be_inlined) {
1448 Map* map = lookup.holder()->map(); 1466 Map* map = lookup.holder()->map();
1449 // Property's index in the properties array. If negative we have 1467 // Property's index in the properties array. If negative we have
1450 // an inobject property. 1468 // an inobject property.
1451 int index = lookup.GetFieldIndex() - map->inobject_properties(); 1469 int index = lookup.GetFieldIndex() - map->inobject_properties();
1452 if (index < 0) { 1470 if (index < 0) {
1453 // Index is an offset from the end of the object. 1471 // Index is an offset from the end of the object.
1454 int offset = map->instance_size() + (index * kPointerSize); 1472 int offset = map->instance_size() + (index * kPointerSize);
1455 if (PatchInlinedStore(address(), map, offset)) { 1473 if (PatchInlinedStore(address(), map, offset)) {
1456 set_target(megamorphic_stub()); 1474 set_target((strict_mode == kStrictMode)
1475 ? megamorphic_stub_strict()
1476 : megamorphic_stub());
1457 #ifdef DEBUG 1477 #ifdef DEBUG
1458 if (FLAG_trace_ic) { 1478 if (FLAG_trace_ic) {
1459 PrintF("[StoreIC : inline patch %s]\n", *name->ToCString()); 1479 PrintF("[StoreIC : inline patch %s]\n", *name->ToCString());
1460 } 1480 }
1461 #endif 1481 #endif
1462 return receiver->SetProperty(*name, *value, NONE); 1482 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1463 #ifdef DEBUG 1483 #ifdef DEBUG
1464 1484
1465 } else { 1485 } else {
1466 if (FLAG_trace_ic) { 1486 if (FLAG_trace_ic) {
1467 PrintF("[StoreIC : no inline patch %s (patching failed)]\n", 1487 PrintF("[StoreIC : no inline patch %s (patching failed)]\n",
1468 *name->ToCString()); 1488 *name->ToCString());
1469 } 1489 }
1470 } 1490 }
1471 } else { 1491 } else {
1472 if (FLAG_trace_ic) { 1492 if (FLAG_trace_ic) {
1473 PrintF("[StoreIC : no inline patch %s (not inobject)]\n", 1493 PrintF("[StoreIC : no inline patch %s (not inobject)]\n",
1474 *name->ToCString()); 1494 *name->ToCString());
1475 } 1495 }
1476 } 1496 }
1477 } else { 1497 } else {
1478 if (state == PREMONOMORPHIC) { 1498 if (state == PREMONOMORPHIC) {
1479 if (FLAG_trace_ic) { 1499 if (FLAG_trace_ic) {
1480 PrintF("[StoreIC : no inline patch %s (not inlinable)]\n", 1500 PrintF("[StoreIC : no inline patch %s (not inlinable)]\n",
1481 *name->ToCString()); 1501 *name->ToCString());
1482 #endif 1502 #endif
1483 } 1503 }
1484 } 1504 }
1485 } 1505 }
1486 1506
1487 // If no inlined store ic was patched, generate a stub for this 1507 // If no inlined store ic was patched, generate a stub for this
1488 // store. 1508 // store.
1489 UpdateCaches(&lookup, state, receiver, name, value); 1509 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1510 } else {
1511 // Strict mode doesn't allow setting non-existent global property
1512 // or an assignment to a read only property.
1513 if (strict_mode == kStrictMode) {
1514 if (lookup.IsFound() && lookup.IsReadOnly()) {
1515 return TypeError("strict_read_only_property", object, name);
1516 } else if (IsContextual(object)) {
1517 return ReferenceError("not_defined", name);
1518 }
1519 }
1490 } 1520 }
1491 } 1521 }
1492 1522
1493 if (receiver->IsJSGlobalProxy()) { 1523 if (receiver->IsJSGlobalProxy()) {
1494 // Generate a generic stub that goes to the runtime when we see a global 1524 // Generate a generic stub that goes to the runtime when we see a global
1495 // proxy as receiver. 1525 // proxy as receiver.
1496 if (target() != global_proxy_stub()) { 1526 Code* stub = (strict_mode == kStrictMode)
1497 set_target(global_proxy_stub()); 1527 ? global_proxy_stub_strict()
1528 : global_proxy_stub();
1529 if (target() != stub) {
1530 set_target(stub);
1498 #ifdef DEBUG 1531 #ifdef DEBUG
1499 TraceIC("StoreIC", name, state, target()); 1532 TraceIC("StoreIC", name, state, target());
1500 #endif 1533 #endif
1501 } 1534 }
1502 } 1535 }
1503 1536
1504 // Set the property. 1537 // Set the property.
1505 return receiver->SetProperty(*name, *value, NONE); 1538 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1506 } 1539 }
1507 1540
1508 1541
1509 void StoreIC::UpdateCaches(LookupResult* lookup, 1542 void StoreIC::UpdateCaches(LookupResult* lookup,
1510 State state, 1543 State state,
1544 StrictModeFlag strict_mode,
1511 Handle<JSObject> receiver, 1545 Handle<JSObject> receiver,
1512 Handle<String> name, 1546 Handle<String> name,
1513 Handle<Object> value) { 1547 Handle<Object> value) {
1514 // Skip JSGlobalProxy. 1548 // Skip JSGlobalProxy.
1515 ASSERT(!receiver->IsJSGlobalProxy()); 1549 ASSERT(!receiver->IsJSGlobalProxy());
1516 1550
1517 ASSERT(StoreICableLookup(lookup)); 1551 ASSERT(StoreICableLookup(lookup));
1518 1552
1519 // If the property has a non-field type allowing map transitions 1553 // If the property has a non-field type allowing map transitions
1520 // where there is extra room in the object, we leave the IC in its 1554 // where there is extra room in the object, we leave the IC in its
1521 // current state. 1555 // current state.
1522 PropertyType type = lookup->type(); 1556 PropertyType type = lookup->type();
1523 1557
1524 // Compute the code stub for this store; used for rewriting to 1558 // Compute the code stub for this store; used for rewriting to
1525 // monomorphic state and making sure that the code stub is in the 1559 // monomorphic state and making sure that the code stub is in the
1526 // stub cache. 1560 // stub cache.
1527 MaybeObject* maybe_code = NULL; 1561 MaybeObject* maybe_code = NULL;
1528 Object* code = NULL; 1562 Object* code = NULL;
1529 switch (type) { 1563 switch (type) {
1530 case FIELD: { 1564 case FIELD: {
1531 maybe_code = isolate()->stub_cache()->ComputeStoreField( 1565 maybe_code = isolate()->stub_cache()->ComputeStoreField(
1532 *name, *receiver, lookup->GetFieldIndex()); 1566 *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode);
1533 break; 1567 break;
1534 } 1568 }
1535 case MAP_TRANSITION: { 1569 case MAP_TRANSITION: {
1536 if (lookup->GetAttributes() != NONE) return; 1570 if (lookup->GetAttributes() != NONE) return;
1537 HandleScope scope(isolate()); 1571 HandleScope scope(isolate());
1538 ASSERT(type == MAP_TRANSITION); 1572 ASSERT(type == MAP_TRANSITION);
1539 Handle<Map> transition(lookup->GetTransitionMap()); 1573 Handle<Map> transition(lookup->GetTransitionMap());
1540 int index = transition->PropertyIndexFor(*name); 1574 int index = transition->PropertyIndexFor(*name);
1541 maybe_code = isolate()->stub_cache()->ComputeStoreField( 1575 maybe_code = isolate()->stub_cache()->ComputeStoreField(
1542 *name, *receiver, index, *transition); 1576 *name, *receiver, index, *transition, strict_mode);
1543 break; 1577 break;
1544 } 1578 }
1545 case NORMAL: { 1579 case NORMAL: {
1546 if (receiver->IsGlobalObject()) { 1580 if (receiver->IsGlobalObject()) {
1547 // The stub generated for the global object picks the value directly 1581 // The stub generated for the global object picks the value directly
1548 // from the property cell. So the property must be directly on the 1582 // from the property cell. So the property must be directly on the
1549 // global object. 1583 // global object.
1550 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1584 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1551 JSGlobalPropertyCell* cell = 1585 JSGlobalPropertyCell* cell =
1552 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 1586 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
1553 maybe_code = isolate()->stub_cache()->ComputeStoreGlobal( 1587 maybe_code = isolate()->stub_cache()->ComputeStoreGlobal(
1554 *name, *global, cell); 1588 *name, *global, cell, strict_mode);
1555 } else { 1589 } else {
1556 if (lookup->holder() != *receiver) return; 1590 if (lookup->holder() != *receiver) return;
1557 maybe_code = isolate()->stub_cache()->ComputeStoreNormal(); 1591 maybe_code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
1558 } 1592 }
1559 break; 1593 break;
1560 } 1594 }
1561 case CALLBACKS: { 1595 case CALLBACKS: {
1562 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; 1596 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return;
1563 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1597 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
1564 if (v8::ToCData<Address>(callback->setter()) == 0) return; 1598 if (v8::ToCData<Address>(callback->setter()) == 0) return;
1565 maybe_code = isolate()->stub_cache()->ComputeStoreCallback(*name, 1599 maybe_code = isolate()->stub_cache()->ComputeStoreCallback(
1566 *receiver, 1600 *name, *receiver, callback, strict_mode);
1567 callback);
1568 break; 1601 break;
1569 } 1602 }
1570 case INTERCEPTOR: { 1603 case INTERCEPTOR: {
1571 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); 1604 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
1572 maybe_code = isolate()->stub_cache()->ComputeStoreInterceptor(*name, 1605 maybe_code = isolate()->stub_cache()->ComputeStoreInterceptor(
1573 *receiver); 1606 *name, *receiver, strict_mode);
1574 break; 1607 break;
1575 } 1608 }
1576 default: 1609 default:
1577 return; 1610 return;
1578 } 1611 }
1579 1612
1580 // If we're unable to compute the stub (not enough memory left), we 1613 // If we're unable to compute the stub (not enough memory left), we
1581 // simply avoid updating the caches. 1614 // simply avoid updating the caches.
1582 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; 1615 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
1583 1616
1584 // Patch the call site depending on the state of the cache. 1617 // Patch the call site depending on the state of the cache.
1585 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { 1618 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1586 set_target(Code::cast(code)); 1619 set_target(Code::cast(code));
1587 } else if (state == MONOMORPHIC) { 1620 } else if (state == MONOMORPHIC) {
1588 // Only move to megamorphic if the target changes. 1621 // Only move to megamorphic if the target changes.
1589 if (target() != Code::cast(code)) set_target(megamorphic_stub()); 1622 if (target() != Code::cast(code)) {
1623 set_target((strict_mode == kStrictMode)
1624 ? megamorphic_stub_strict()
1625 : megamorphic_stub());
1626 }
1590 } else if (state == MEGAMORPHIC) { 1627 } else if (state == MEGAMORPHIC) {
1591 // Update the stub cache. 1628 // Update the stub cache.
1592 isolate()->stub_cache()->Set(*name, 1629 isolate()->stub_cache()->Set(*name,
1593 receiver->map(), 1630 receiver->map(),
1594 Code::cast(code)); 1631 Code::cast(code));
1595 } 1632 }
1596 1633
1597 #ifdef DEBUG 1634 #ifdef DEBUG
1598 TraceIC("StoreIC", name, state, target()); 1635 TraceIC("StoreIC", name, state, target());
1599 #endif 1636 #endif
1600 } 1637 }
1601 1638
1602 1639
1603 MaybeObject* KeyedStoreIC::Store(State state, 1640 MaybeObject* KeyedStoreIC::Store(State state,
1641 StrictModeFlag strict_mode,
1604 Handle<Object> object, 1642 Handle<Object> object,
1605 Handle<Object> key, 1643 Handle<Object> key,
1606 Handle<Object> value) { 1644 Handle<Object> value) {
1607 if (key->IsSymbol()) { 1645 if (key->IsSymbol()) {
1608 Handle<String> name = Handle<String>::cast(key); 1646 Handle<String> name = Handle<String>::cast(key);
1609 1647
1610 // If the object is undefined or null it's illegal to try to set any 1648 // If the object is undefined or null it's illegal to try to set any
1611 // properties on it; throw a TypeError in that case. 1649 // properties on it; throw a TypeError in that case.
1612 if (object->IsUndefined() || object->IsNull()) { 1650 if (object->IsUndefined() || object->IsNull()) {
1613 return TypeError("non_object_property_store", object, name); 1651 return TypeError("non_object_property_store", object, name);
(...skipping 11 matching lines...) Expand all
1625 if (result.is_null()) return Failure::Exception(); 1663 if (result.is_null()) return Failure::Exception();
1626 return *value; 1664 return *value;
1627 } 1665 }
1628 1666
1629 // Lookup the property locally in the receiver. 1667 // Lookup the property locally in the receiver.
1630 LookupResult lookup; 1668 LookupResult lookup;
1631 receiver->LocalLookup(*name, &lookup); 1669 receiver->LocalLookup(*name, &lookup);
1632 1670
1633 // Update inline cache and stub cache. 1671 // Update inline cache and stub cache.
1634 if (FLAG_use_ic) { 1672 if (FLAG_use_ic) {
1635 UpdateCaches(&lookup, state, receiver, name, value); 1673 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1636 } 1674 }
1637 1675
1638 // Set the property. 1676 // Set the property.
1639 return receiver->SetProperty(*name, *value, NONE); 1677 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1640 } 1678 }
1641 1679
1642 // Do not use ICs for objects that require access checks (including 1680 // Do not use ICs for objects that require access checks (including
1643 // the global object). 1681 // the global object).
1644 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 1682 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
1645 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 1683 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
1646 1684
1647 if (use_ic) { 1685 if (use_ic) {
1648 Code* stub = generic_stub(); 1686 Code* stub =
1649 if (object->IsJSObject()) { 1687 (strict_mode == kStrictMode) ? generic_stub_strict() : generic_stub();
1650 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1688 if (state == UNINITIALIZED) {
1651 if (receiver->HasExternalArrayElements()) { 1689 if (object->IsJSObject()) {
1652 MaybeObject* probe = 1690 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1653 isolate()->stub_cache()->ComputeKeyedLoadOrStoreExternalArray( 1691 if (receiver->HasExternalArrayElements()) {
1654 *receiver, true); 1692 MaybeObject* probe =
1655 stub = 1693 isolate()->stub_cache()->ComputeKeyedLoadOrStoreExternalArray(
1656 probe->IsFailure() ? NULL : Code::cast(probe->ToObjectUnchecked()); 1694 *receiver, true, strict_mode);
1657 } else if (state == UNINITIALIZED && 1695 stub = probe->IsFailure() ?
1658 key->IsSmi() && 1696 NULL : Code::cast(probe->ToObjectUnchecked());
1659 receiver->map()->has_fast_elements()) { 1697 } else if (receiver->HasPixelElements()) {
1660 MaybeObject* probe = 1698 MaybeObject* probe =
1661 isolate()->stub_cache()->ComputeKeyedStoreSpecialized(*receiver); 1699 isolate()->stub_cache()->ComputeKeyedStorePixelArray(
1662 stub = 1700 *receiver, strict_mode);
1663 probe->IsFailure() ? NULL : Code::cast(probe->ToObjectUnchecked()); 1701 stub = probe->IsFailure() ?
1702 NULL : Code::cast(probe->ToObjectUnchecked());
1703 } else if (key->IsSmi() && receiver->map()->has_fast_elements()) {
1704 MaybeObject* probe =
1705 isolate()->stub_cache()->ComputeKeyedStoreSpecialized(
1706 *receiver, strict_mode);
1707 stub = probe->IsFailure() ?
1708 NULL : Code::cast(probe->ToObjectUnchecked());
1709 }
1664 } 1710 }
1665 } 1711 }
1666 if (stub != NULL) set_target(stub); 1712 if (stub != NULL) set_target(stub);
1667 } 1713 }
1668 1714
1669 // Set the property. 1715 // Set the property.
1670 return Runtime::SetObjectProperty(isolate(), object, key, value, NONE); 1716 return Runtime::SetObjectProperty(
1717 isolate(), object , key, value, NONE, strict_mode);
1671 } 1718 }
1672 1719
1673 1720
1674 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, 1721 void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
1675 State state, 1722 State state,
1723 StrictModeFlag strict_mode,
1676 Handle<JSObject> receiver, 1724 Handle<JSObject> receiver,
1677 Handle<String> name, 1725 Handle<String> name,
1678 Handle<Object> value) { 1726 Handle<Object> value) {
1679 // Skip JSGlobalProxy. 1727 // Skip JSGlobalProxy.
1680 if (receiver->IsJSGlobalProxy()) return; 1728 if (receiver->IsJSGlobalProxy()) return;
1681 1729
1682 // Bail out if we didn't find a result. 1730 // Bail out if we didn't find a result.
1683 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return; 1731 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return;
1684 1732
1685 // If the property is read-only, we leave the IC in its current 1733 // If the property is read-only, we leave the IC in its current
1686 // state. 1734 // state.
1687 if (lookup->IsReadOnly()) return; 1735 if (lookup->IsReadOnly()) return;
1688 1736
1689 // If the property has a non-field type allowing map transitions 1737 // If the property has a non-field type allowing map transitions
1690 // where there is extra room in the object, we leave the IC in its 1738 // where there is extra room in the object, we leave the IC in its
1691 // current state. 1739 // current state.
1692 PropertyType type = lookup->type(); 1740 PropertyType type = lookup->type();
1693 1741
1694 // Compute the code stub for this store; used for rewriting to 1742 // Compute the code stub for this store; used for rewriting to
1695 // monomorphic state and making sure that the code stub is in the 1743 // monomorphic state and making sure that the code stub is in the
1696 // stub cache. 1744 // stub cache.
1697 MaybeObject* maybe_code = NULL; 1745 MaybeObject* maybe_code = NULL;
1698 Object* code = NULL; 1746 Object* code = NULL;
1699 1747
1700 switch (type) { 1748 switch (type) {
1701 case FIELD: { 1749 case FIELD: {
1702 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( 1750 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField(
1703 *name, *receiver, lookup->GetFieldIndex()); 1751 *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode);
1704 break; 1752 break;
1705 } 1753 }
1706 case MAP_TRANSITION: { 1754 case MAP_TRANSITION: {
1707 if (lookup->GetAttributes() == NONE) { 1755 if (lookup->GetAttributes() == NONE) {
1708 HandleScope scope(isolate()); 1756 HandleScope scope(isolate());
1709 ASSERT(type == MAP_TRANSITION); 1757 ASSERT(type == MAP_TRANSITION);
1710 Handle<Map> transition(lookup->GetTransitionMap()); 1758 Handle<Map> transition(lookup->GetTransitionMap());
1711 int index = transition->PropertyIndexFor(*name); 1759 int index = transition->PropertyIndexFor(*name);
1712 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( 1760 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField(
1713 *name, *receiver, index, *transition); 1761 *name, *receiver, index, *transition, strict_mode);
1714 break; 1762 break;
1715 } 1763 }
1716 // fall through. 1764 // fall through.
1717 } 1765 }
1718 default: { 1766 default: {
1719 // Always rewrite to the generic case so that we do not 1767 // Always rewrite to the generic case so that we do not
1720 // repeatedly try to rewrite. 1768 // repeatedly try to rewrite.
1721 maybe_code = generic_stub(); 1769 maybe_code = (strict_mode == kStrictMode)
1770 ? generic_stub_strict()
1771 : generic_stub();
1722 break; 1772 break;
1723 } 1773 }
1724 } 1774 }
1725 1775
1726 // If we're unable to compute the stub (not enough memory left), we 1776 // If we're unable to compute the stub (not enough memory left), we
1727 // simply avoid updating the caches. 1777 // simply avoid updating the caches.
1728 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; 1778 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
1729 1779
1730 // Patch the call site depending on the state of the cache. Make 1780 // Patch the call site depending on the state of the cache. Make
1731 // sure to always rewrite from monomorphic to megamorphic. 1781 // sure to always rewrite from monomorphic to megamorphic.
1732 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); 1782 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1733 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { 1783 if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1734 set_target(Code::cast(code)); 1784 set_target(Code::cast(code));
1735 } else if (state == MONOMORPHIC) { 1785 } else if (state == MONOMORPHIC) {
1736 set_target(megamorphic_stub()); 1786 set_target((strict_mode == kStrictMode)
1787 ? megamorphic_stub_strict()
1788 : megamorphic_stub());
1737 } 1789 }
1738 1790
1739 #ifdef DEBUG 1791 #ifdef DEBUG
1740 TraceIC("KeyedStoreIC", name, state, target()); 1792 TraceIC("KeyedStoreIC", name, state, target());
1741 #endif 1793 #endif
1742 } 1794 }
1743 1795
1744 1796
1745 // ---------------------------------------------------------------------------- 1797 // ----------------------------------------------------------------------------
1746 // Static IC stub generators. 1798 // Static IC stub generators.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 } 1888 }
1837 1889
1838 1890
1839 // Used from ic-<arch>.cc. 1891 // Used from ic-<arch>.cc.
1840 MUST_USE_RESULT MaybeObject* StoreIC_Miss(RUNTIME_CALLING_CONVENTION) { 1892 MUST_USE_RESULT MaybeObject* StoreIC_Miss(RUNTIME_CALLING_CONVENTION) {
1841 RUNTIME_GET_ISOLATE; 1893 RUNTIME_GET_ISOLATE;
1842 NoHandleAllocation na; 1894 NoHandleAllocation na;
1843 ASSERT(args.length() == 3); 1895 ASSERT(args.length() == 3);
1844 StoreIC ic(isolate); 1896 StoreIC ic(isolate);
1845 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1897 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1846 return ic.Store(state, args.at<Object>(0), args.at<String>(1), 1898 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1899 return ic.Store(state,
1900 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode),
1901 args.at<Object>(0),
1902 args.at<String>(1),
1847 args.at<Object>(2)); 1903 args.at<Object>(2));
1848 } 1904 }
1849 1905
1850 1906
1851 MUST_USE_RESULT MaybeObject* StoreIC_ArrayLength(RUNTIME_CALLING_CONVENTION) { 1907 MUST_USE_RESULT MaybeObject* StoreIC_ArrayLength(RUNTIME_CALLING_CONVENTION) {
1852 RUNTIME_GET_ISOLATE; 1908 RUNTIME_GET_ISOLATE;
1853 NoHandleAllocation nha; 1909 NoHandleAllocation nha;
1854 1910
1855 ASSERT(args.length() == 2); 1911 ASSERT(args.length() == 2);
1856 JSObject* receiver = JSObject::cast(args[0]); 1912 JSObject* receiver = JSObject::cast(args[0]);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 } 1961 }
1906 1962
1907 1963
1908 // Used from ic-<arch>.cc. 1964 // Used from ic-<arch>.cc.
1909 MUST_USE_RESULT MaybeObject* KeyedStoreIC_Miss(RUNTIME_CALLING_CONVENTION) { 1965 MUST_USE_RESULT MaybeObject* KeyedStoreIC_Miss(RUNTIME_CALLING_CONVENTION) {
1910 RUNTIME_GET_ISOLATE; 1966 RUNTIME_GET_ISOLATE;
1911 NoHandleAllocation na; 1967 NoHandleAllocation na;
1912 ASSERT(args.length() == 3); 1968 ASSERT(args.length() == 3);
1913 KeyedStoreIC ic(isolate); 1969 KeyedStoreIC ic(isolate);
1914 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1970 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1915 return ic.Store(state, args.at<Object>(0), args.at<Object>(1), 1971 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1972 return ic.Store(state,
1973 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode),
1974 args.at<Object>(0),
1975 args.at<Object>(1),
1916 args.at<Object>(2)); 1976 args.at<Object>(2));
1917 } 1977 }
1918 1978
1919 1979
1920 void BinaryOpIC::patch(Code* code) { 1980 void BinaryOpIC::patch(Code* code) {
1921 set_target(code); 1981 set_target(code);
1922 } 1982 }
1923 1983
1924 1984
1925 const char* BinaryOpIC::GetName(TypeInfo type_info) { 1985 const char* BinaryOpIC::GetName(TypeInfo type_info) {
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 #undef ADDR 2375 #undef ADDR
2316 }; 2376 };
2317 2377
2318 2378
2319 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2379 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2320 return IC_utilities[id]; 2380 return IC_utilities[id];
2321 } 2381 }
2322 2382
2323 2383
2324 } } // namespace v8::internal 2384 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698