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

Side by Side Diff: src/ic.cc

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 return 0; 58 return 0;
59 } 59 }
60 60
61 void IC::TraceIC(const char* type, 61 void IC::TraceIC(const char* type,
62 Handle<Object> name, 62 Handle<Object> name,
63 State old_state, 63 State old_state,
64 Code* new_target, 64 Code* new_target,
65 const char* extra_info) { 65 const char* extra_info) {
66 if (FLAG_trace_ic) { 66 if (FLAG_trace_ic) {
67 State new_state = StateFrom(new_target, 67 State new_state = StateFrom(new_target,
68 Heap::undefined_value(), 68 HEAP->undefined_value(),
69 Heap::undefined_value()); 69 HEAP->undefined_value());
70 PrintF("[%s (%c->%c)%s", type, 70 PrintF("[%s (%c->%c)%s", type,
71 TransitionMarkFromState(old_state), 71 TransitionMarkFromState(old_state),
72 TransitionMarkFromState(new_state), 72 TransitionMarkFromState(new_state),
73 extra_info); 73 extra_info);
74 name->Print(); 74 name->Print();
75 PrintF("]\n"); 75 PrintF("]\n");
76 } 76 }
77 } 77 }
78 #endif 78 #endif
79 79
80 80
81 IC::IC(FrameDepth depth) { 81 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
82 ASSERT(isolate == Isolate::Current());
82 // To improve the performance of the (much used) IC code, we unfold 83 // To improve the performance of the (much used) IC code, we unfold
83 // a few levels of the stack frame iteration code. This yields a 84 // a few levels of the stack frame iteration code. This yields a
84 // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag. 85 // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag.
85 const Address entry = Top::c_entry_fp(Top::GetCurrentThread()); 86 const Address entry =
87 Isolate::c_entry_fp(isolate->thread_local_top());
86 Address* pc_address = 88 Address* pc_address =
87 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); 89 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
88 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 90 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
89 // If there's another JavaScript frame on the stack, we need to look 91 // If there's another JavaScript frame on the stack, we need to look
90 // one frame further down the stack to find the frame pointer and 92 // one frame further down the stack to find the frame pointer and
91 // the return address stack slot. 93 // the return address stack slot.
92 if (depth == EXTRA_CALL_FRAME) { 94 if (depth == EXTRA_CALL_FRAME) {
93 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; 95 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset;
94 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); 96 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset);
95 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); 97 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // Return the address in the original code. This is the place where 131 // Return the address in the original code. This is the place where
130 // the call which has been overwritten by the DebugBreakXXX resides 132 // the call which has been overwritten by the DebugBreakXXX resides
131 // and the place where the inline cache system should look. 133 // and the place where the inline cache system should look.
132 intptr_t delta = 134 intptr_t delta =
133 original_code->instruction_start() - code->instruction_start(); 135 original_code->instruction_start() - code->instruction_start();
134 return addr + delta; 136 return addr + delta;
135 } 137 }
136 #endif 138 #endif
137 139
138 140
139 static bool HasNormalObjectsInPrototypeChain(LookupResult* lookup, 141 static bool HasNormalObjectsInPrototypeChain(Isolate* isolate,
142 LookupResult* lookup,
140 Object* receiver) { 143 Object* receiver) {
141 Object* end = lookup->IsProperty() ? lookup->holder() : Heap::null_value(); 144 Object* end = lookup->IsProperty()
145 ? lookup->holder() : isolate->heap()->null_value();
142 for (Object* current = receiver; 146 for (Object* current = receiver;
143 current != end; 147 current != end;
144 current = current->GetPrototype()) { 148 current = current->GetPrototype()) {
145 if (current->IsJSObject() && 149 if (current->IsJSObject() &&
146 !JSObject::cast(current)->HasFastProperties() && 150 !JSObject::cast(current)->HasFastProperties() &&
147 !current->IsJSGlobalProxy() && 151 !current->IsJSGlobalProxy() &&
148 !current->IsJSGlobalObject()) { 152 !current->IsJSGlobalObject()) {
149 return true; 153 return true;
150 } 154 }
151 } 155 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 if (receiver->IsJSBuiltinsObject()) { 228 if (receiver->IsJSBuiltinsObject()) {
225 return UNINITIALIZED; 229 return UNINITIALIZED;
226 } 230 }
227 231
228 return MONOMORPHIC; 232 return MONOMORPHIC;
229 } 233 }
230 234
231 235
232 RelocInfo::Mode IC::ComputeMode() { 236 RelocInfo::Mode IC::ComputeMode() {
233 Address addr = address(); 237 Address addr = address();
234 Code* code = Code::cast(Heap::FindCodeObject(addr)); 238 Code* code = Code::cast(isolate()->heap()->FindCodeObject(addr));
235 for (RelocIterator it(code, RelocInfo::kCodeTargetMask); 239 for (RelocIterator it(code, RelocInfo::kCodeTargetMask);
236 !it.done(); it.next()) { 240 !it.done(); it.next()) {
237 RelocInfo* info = it.rinfo(); 241 RelocInfo* info = it.rinfo();
238 if (info->pc() == addr) return info->rmode(); 242 if (info->pc() == addr) return info->rmode();
239 } 243 }
240 UNREACHABLE(); 244 UNREACHABLE();
241 return RelocInfo::NONE; 245 return RelocInfo::NONE;
242 } 246 }
243 247
244 248
245 Failure* IC::TypeError(const char* type, 249 Failure* IC::TypeError(const char* type,
246 Handle<Object> object, 250 Handle<Object> object,
247 Handle<Object> key) { 251 Handle<Object> key) {
248 HandleScope scope; 252 HandleScope scope(isolate());
249 Handle<Object> args[2] = { key, object }; 253 Handle<Object> args[2] = { key, object };
250 Handle<Object> error = Factory::NewTypeError(type, HandleVector(args, 2)); 254 Handle<Object> error = isolate()->factory()->NewTypeError(
251 return Top::Throw(*error); 255 type, HandleVector(args, 2));
256 return isolate()->Throw(*error);
252 } 257 }
253 258
254 259
255 Failure* IC::ReferenceError(const char* type, Handle<String> name) { 260 Failure* IC::ReferenceError(const char* type, Handle<String> name) {
256 HandleScope scope; 261 HandleScope scope(isolate());
257 Handle<Object> error = 262 Handle<Object> error = isolate()->factory()->NewReferenceError(
258 Factory::NewReferenceError(type, HandleVector(&name, 1)); 263 type, HandleVector(&name, 1));
259 return Top::Throw(*error); 264 return isolate()->Throw(*error);
260 } 265 }
261 266
262 267
263 void IC::Clear(Address address) { 268 void IC::Clear(Address address) {
264 Code* target = GetTargetAtAddress(address); 269 Code* target = GetTargetAtAddress(address);
265 270
266 // Don't clear debug break inline cache as it will remove the break point. 271 // Don't clear debug break inline cache as it will remove the break point.
267 if (target->ic_state() == DEBUG_BREAK) return; 272 if (target->ic_state() == DEBUG_BREAK) return;
268 273
269 switch (target->kind()) { 274 switch (target->kind()) {
(...skipping 15 matching lines...) Expand all
285 return; 290 return;
286 default: UNREACHABLE(); 291 default: UNREACHABLE();
287 } 292 }
288 } 293 }
289 294
290 295
291 void CallICBase::Clear(Address address, Code* target) { 296 void CallICBase::Clear(Address address, Code* target) {
292 State state = target->ic_state(); 297 State state = target->ic_state();
293 if (state == UNINITIALIZED) return; 298 if (state == UNINITIALIZED) return;
294 Code* code = 299 Code* code =
295 StubCache::FindCallInitialize(target->arguments_count(), 300 Isolate::Current()->stub_cache()->FindCallInitialize(
296 target->ic_in_loop(), 301 target->arguments_count(),
297 target->kind()); 302 target->ic_in_loop(),
303 target->kind());
298 SetTargetAtAddress(address, code); 304 SetTargetAtAddress(address, code);
299 } 305 }
300 306
301 307
302 void KeyedLoadIC::ClearInlinedVersion(Address address) { 308 void KeyedLoadIC::ClearInlinedVersion(Address address) {
303 // Insert null as the map to check for to make sure the map check fails 309 // Insert null as the map to check for to make sure the map check fails
304 // sending control flow to the IC instead of the inlined version. 310 // sending control flow to the IC instead of the inlined version.
305 PatchInlinedLoad(address, Heap::null_value()); 311 PatchInlinedLoad(address, HEAP->null_value());
306 } 312 }
307 313
308 314
309 void KeyedLoadIC::Clear(Address address, Code* target) { 315 void KeyedLoadIC::Clear(Address address, Code* target) {
310 if (target->ic_state() == UNINITIALIZED) return; 316 if (target->ic_state() == UNINITIALIZED) return;
311 // Make sure to also clear the map used in inline fast cases. If we 317 // Make sure to also clear the map used in inline fast cases. If we
312 // do not clear these maps, cached code can keep objects alive 318 // do not clear these maps, cached code can keep objects alive
313 // through the embedded maps. 319 // through the embedded maps.
314 ClearInlinedVersion(address); 320 ClearInlinedVersion(address);
315 SetTargetAtAddress(address, initialize_stub()); 321 SetTargetAtAddress(address, initialize_stub());
316 } 322 }
317 323
318 324
319 void LoadIC::ClearInlinedVersion(Address address) { 325 void LoadIC::ClearInlinedVersion(Address address) {
320 // Reset the map check of the inlined inobject property load (if 326 // Reset the map check of the inlined inobject property load (if
321 // present) to guarantee failure by holding an invalid map (the null 327 // present) to guarantee failure by holding an invalid map (the null
322 // value). The offset can be patched to anything. 328 // value). The offset can be patched to anything.
323 PatchInlinedLoad(address, Heap::null_value(), 0); 329 Heap* heap = HEAP;
330 PatchInlinedLoad(address, heap->null_value(), 0);
324 PatchInlinedContextualLoad(address, 331 PatchInlinedContextualLoad(address,
325 Heap::null_value(), 332 heap->null_value(),
326 Heap::null_value(), 333 heap->null_value(),
327 true); 334 true);
328 } 335 }
329 336
330 337
331 void LoadIC::Clear(Address address, Code* target) { 338 void LoadIC::Clear(Address address, Code* target) {
332 if (target->ic_state() == UNINITIALIZED) return; 339 if (target->ic_state() == UNINITIALIZED) return;
333 ClearInlinedVersion(address); 340 ClearInlinedVersion(address);
334 SetTargetAtAddress(address, initialize_stub()); 341 SetTargetAtAddress(address, initialize_stub());
335 } 342 }
336 343
337 344
338 void StoreIC::ClearInlinedVersion(Address address) { 345 void StoreIC::ClearInlinedVersion(Address address) {
339 // Reset the map check of the inlined inobject property store (if 346 // Reset the map check of the inlined inobject property store (if
340 // present) to guarantee failure by holding an invalid map (the null 347 // present) to guarantee failure by holding an invalid map (the null
341 // value). The offset can be patched to anything. 348 // value). The offset can be patched to anything.
342 PatchInlinedStore(address, Heap::null_value(), 0); 349 PatchInlinedStore(address, HEAP->null_value(), 0);
343 } 350 }
344 351
345 352
346 void StoreIC::Clear(Address address, Code* target) { 353 void StoreIC::Clear(Address address, Code* target) {
347 if (target->ic_state() == UNINITIALIZED) return; 354 if (target->ic_state() == UNINITIALIZED) return;
348 ClearInlinedVersion(address); 355 ClearInlinedVersion(address);
349 SetTargetAtAddress(address, 356 SetTargetAtAddress(address,
350 (target->extra_ic_state() == kStrictMode) 357 (target->extra_ic_state() == kStrictMode)
351 ? initialize_stub_strict() 358 ? initialize_stub_strict()
352 : initialize_stub()); 359 : initialize_stub());
353 } 360 }
354 361
355 362
356 void KeyedStoreIC::ClearInlinedVersion(Address address) { 363 void KeyedStoreIC::ClearInlinedVersion(Address address) {
357 // Insert null as the elements map to check for. This will make 364 // 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 365 // sure that the elements fast-case map check fails so that control
359 // flows to the IC instead of the inlined version. 366 // flows to the IC instead of the inlined version.
360 PatchInlinedStore(address, Heap::null_value()); 367 PatchInlinedStore(address, HEAP->null_value());
361 } 368 }
362 369
363 370
364 void KeyedStoreIC::RestoreInlinedVersion(Address address) { 371 void KeyedStoreIC::RestoreInlinedVersion(Address address) {
365 // Restore the fast-case elements map check so that the inlined 372 // Restore the fast-case elements map check so that the inlined
366 // version can be used again. 373 // version can be used again.
367 PatchInlinedStore(address, Heap::fixed_array_map()); 374 PatchInlinedStore(address, HEAP->fixed_array_map());
368 } 375 }
369 376
370 377
371 void KeyedStoreIC::Clear(Address address, Code* target) { 378 void KeyedStoreIC::Clear(Address address, Code* target) {
372 if (target->ic_state() == UNINITIALIZED) return; 379 if (target->ic_state() == UNINITIALIZED) return;
373 SetTargetAtAddress(address, 380 SetTargetAtAddress(address,
374 (target->extra_ic_state() == kStrictMode) 381 (target->extra_ic_state() == kStrictMode)
375 ? initialize_stub_strict() 382 ? initialize_stub_strict()
376 : initialize_stub()); 383 : initialize_stub());
377 } 384 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 lookup->NotFound(); 423 lookup->NotFound();
417 return; 424 return;
418 } 425 }
419 426
420 object = proto; 427 object = proto;
421 } 428 }
422 } 429 }
423 430
424 431
425 Object* CallICBase::TryCallAsFunction(Object* object) { 432 Object* CallICBase::TryCallAsFunction(Object* object) {
426 HandleScope scope; 433 HandleScope scope(isolate());
427 Handle<Object> target(object); 434 Handle<Object> target(object, isolate());
428 Handle<Object> delegate = Execution::GetFunctionDelegate(target); 435 Handle<Object> delegate = Execution::GetFunctionDelegate(target);
429 436
430 if (delegate->IsJSFunction()) { 437 if (delegate->IsJSFunction()) {
431 // Patch the receiver and use the delegate as the function to 438 // Patch the receiver and use the delegate as the function to
432 // invoke. This is used for invoking objects as if they were 439 // invoke. This is used for invoking objects as if they were
433 // functions. 440 // functions.
434 const int argc = this->target()->arguments_count(); 441 const int argc = this->target()->arguments_count();
435 StackFrameLocator locator; 442 StackFrameLocator locator;
436 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 443 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
437 int index = frame->ComputeExpressionsCount() - (argc + 1); 444 int index = frame->ComputeExpressionsCount() - (argc + 1);
(...skipping 14 matching lines...) Expand all
452 } 459 }
453 } 460 }
454 461
455 // And only wrap string, number or boolean. 462 // And only wrap string, number or boolean.
456 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { 463 if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
457 // Change the receiver to the result of calling ToObject on it. 464 // Change the receiver to the result of calling ToObject on it.
458 const int argc = this->target()->arguments_count(); 465 const int argc = this->target()->arguments_count();
459 StackFrameLocator locator; 466 StackFrameLocator locator;
460 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 467 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
461 int index = frame->ComputeExpressionsCount() - (argc + 1); 468 int index = frame->ComputeExpressionsCount() - (argc + 1);
462 frame->SetExpression(index, *Factory::ToObject(object)); 469 frame->SetExpression(index, *isolate()->factory()->ToObject(object));
463 } 470 }
464 } 471 }
465 472
466 473
467 MaybeObject* CallICBase::LoadFunction(State state, 474 MaybeObject* CallICBase::LoadFunction(State state,
468 Code::ExtraICState extra_ic_state, 475 Code::ExtraICState extra_ic_state,
469 Handle<Object> object, 476 Handle<Object> object,
470 Handle<String> name) { 477 Handle<String> name) {
471 // If the object is undefined or null it's illegal to try to get any 478 // If the object is undefined or null it's illegal to try to get any
472 // of its properties; throw a TypeError in that case. 479 // of its properties; throw a TypeError in that case.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 if (attr == ABSENT) { 531 if (attr == ABSENT) {
525 if (IsContextual(object)) { 532 if (IsContextual(object)) {
526 return ReferenceError("not_defined", name); 533 return ReferenceError("not_defined", name);
527 } 534 }
528 return TypeError("undefined_method", object, name); 535 return TypeError("undefined_method", object, name);
529 } 536 }
530 } 537 }
531 538
532 ASSERT(!result->IsTheHole()); 539 ASSERT(!result->IsTheHole());
533 540
534 HandleScope scope; 541 HandleScope scope(isolate());
535 // Wrap result in a handle because ReceiverToObjectIfRequired may allocate 542 // Wrap result in a handle because ReceiverToObjectIfRequired may allocate
536 // new object and cause GC. 543 // new object and cause GC.
537 Handle<Object> result_handle(result); 544 Handle<Object> result_handle(result);
538 // Make receiver an object if the callee requires it. Strict mode or builtin 545 // Make receiver an object if the callee requires it. Strict mode or builtin
539 // functions do not wrap the receiver, non-strict functions and objects 546 // functions do not wrap the receiver, non-strict functions and objects
540 // called as functions do. 547 // called as functions do.
541 ReceiverToObjectIfRequired(result_handle, object); 548 ReceiverToObjectIfRequired(result_handle, object);
542 549
543 if (result_handle->IsJSFunction()) { 550 if (result_handle->IsJSFunction()) {
544 #ifdef ENABLE_DEBUGGER_SUPPORT 551 #ifdef ENABLE_DEBUGGER_SUPPORT
545 // Handle stepping into a function if step into is active. 552 // Handle stepping into a function if step into is active.
546 if (Debug::StepInActive()) { 553 Debug* debug = isolate()->debug();
554 if (debug->StepInActive()) {
547 // Protect the result in a handle as the debugger can allocate and might 555 // Protect the result in a handle as the debugger can allocate and might
548 // cause GC. 556 // cause GC.
549 Handle<JSFunction> function(JSFunction::cast(*result_handle)); 557 Handle<JSFunction> function(JSFunction::cast(*result_handle), isolate());
550 Debug::HandleStepIn(function, object, fp(), false); 558 debug->HandleStepIn(function, object, fp(), false);
551 return *function; 559 return *function;
552 } 560 }
553 #endif 561 #endif
554 562
555 return *result_handle; 563 return *result_handle;
556 } 564 }
557 565
558 // Try to find a suitable function delegate for the object at hand. 566 // Try to find a suitable function delegate for the object at hand.
559 result_handle = Handle<Object>(TryCallAsFunction(*result_handle)); 567 result_handle = Handle<Object>(TryCallAsFunction(*result_handle));
560 if (result_handle->IsJSFunction()) return *result_handle; 568 if (result_handle->IsJSFunction()) return *result_handle;
561 569
562 return TypeError("property_not_function", object, name); 570 return TypeError("property_not_function", object, name);
563 } 571 }
564 572
565 573
566 bool CallICBase::TryUpdateExtraICState(LookupResult* lookup, 574 bool CallICBase::TryUpdateExtraICState(LookupResult* lookup,
567 Handle<Object> object, 575 Handle<Object> object,
568 Code::ExtraICState* extra_ic_state) { 576 Code::ExtraICState* extra_ic_state) {
569 ASSERT(kind_ == Code::CALL_IC); 577 ASSERT(kind_ == Code::CALL_IC);
570 if (lookup->type() != CONSTANT_FUNCTION) return false; 578 if (lookup->type() != CONSTANT_FUNCTION) return false;
571 JSFunction* function = lookup->GetConstantFunction(); 579 JSFunction* function = lookup->GetConstantFunction();
572 if (!function->shared()->HasBuiltinFunctionId()) return false; 580 if (!function->shared()->HasBuiltinFunctionId()) return false;
573 581
574 // Fetch the arguments passed to the called function. 582 // Fetch the arguments passed to the called function.
575 const int argc = target()->arguments_count(); 583 const int argc = target()->arguments_count();
576 Address entry = Top::c_entry_fp(Top::GetCurrentThread()); 584 Address entry = isolate()->c_entry_fp(isolate()->thread_local_top());
577 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 585 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
578 Arguments args(argc + 1, 586 Arguments args(argc + 1,
579 &Memory::Object_at(fp + 587 &Memory::Object_at(fp +
580 StandardFrameConstants::kCallerSPOffset + 588 StandardFrameConstants::kCallerSPOffset +
581 argc * kPointerSize)); 589 argc * kPointerSize));
582 switch (function->shared()->builtin_function_id()) { 590 switch (function->shared()->builtin_function_id()) {
583 case kStringCharCodeAt: 591 case kStringCharCodeAt:
584 case kStringCharAt: 592 case kStringCharAt:
585 if (object->IsString()) { 593 if (object->IsString()) {
586 String* string = String::cast(*object); 594 String* string = String::cast(*object);
(...skipping 29 matching lines...) Expand all
616 State state, 624 State state,
617 Code::ExtraICState extra_ic_state, 625 Code::ExtraICState extra_ic_state,
618 Handle<Object> object, 626 Handle<Object> object,
619 Handle<String> name) { 627 Handle<String> name) {
620 int argc = target()->arguments_count(); 628 int argc = target()->arguments_count();
621 InLoopFlag in_loop = target()->ic_in_loop(); 629 InLoopFlag in_loop = target()->ic_in_loop();
622 MaybeObject* maybe_code = NULL; 630 MaybeObject* maybe_code = NULL;
623 switch (lookup->type()) { 631 switch (lookup->type()) {
624 case FIELD: { 632 case FIELD: {
625 int index = lookup->GetFieldIndex(); 633 int index = lookup->GetFieldIndex();
626 maybe_code = StubCache::ComputeCallField(argc, 634 maybe_code = isolate()->stub_cache()->ComputeCallField(argc,
627 in_loop, 635 in_loop,
628 kind_, 636 kind_,
629 *name, 637 *name,
630 *object, 638 *object,
631 lookup->holder(), 639 lookup->holder(),
632 index); 640 index);
633 break; 641 break;
634 } 642 }
635 case CONSTANT_FUNCTION: { 643 case CONSTANT_FUNCTION: {
636 // Get the constant function and compute the code stub for this 644 // Get the constant function and compute the code stub for this
637 // call; used for rewriting to monomorphic state and making sure 645 // call; used for rewriting to monomorphic state and making sure
638 // that the code stub is in the stub cache. 646 // that the code stub is in the stub cache.
639 JSFunction* function = lookup->GetConstantFunction(); 647 JSFunction* function = lookup->GetConstantFunction();
640 maybe_code = StubCache::ComputeCallConstant(argc, 648 maybe_code =
641 in_loop, 649 isolate()->stub_cache()->ComputeCallConstant(argc,
642 kind_, 650 in_loop,
643 extra_ic_state, 651 kind_,
644 *name, 652 extra_ic_state,
645 *object, 653 *name,
646 lookup->holder(), 654 *object,
647 function); 655 lookup->holder(),
656 function);
648 break; 657 break;
649 } 658 }
650 case NORMAL: { 659 case NORMAL: {
651 if (!object->IsJSObject()) return NULL; 660 if (!object->IsJSObject()) return NULL;
652 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 661 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
653 662
654 if (lookup->holder()->IsGlobalObject()) { 663 if (lookup->holder()->IsGlobalObject()) {
655 GlobalObject* global = GlobalObject::cast(lookup->holder()); 664 GlobalObject* global = GlobalObject::cast(lookup->holder());
656 JSGlobalPropertyCell* cell = 665 JSGlobalPropertyCell* cell =
657 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 666 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
658 if (!cell->value()->IsJSFunction()) return NULL; 667 if (!cell->value()->IsJSFunction()) return NULL;
659 JSFunction* function = JSFunction::cast(cell->value()); 668 JSFunction* function = JSFunction::cast(cell->value());
660 maybe_code = StubCache::ComputeCallGlobal(argc, 669 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc,
661 in_loop, 670 in_loop,
662 kind_, 671 kind_,
663 *name, 672 *name,
664 *receiver, 673 *receiver,
665 global, 674 global,
666 cell, 675 cell,
667 function); 676 function);
668 } else { 677 } else {
669 // There is only one shared stub for calling normalized 678 // There is only one shared stub for calling normalized
670 // properties. It does not traverse the prototype chain, so the 679 // properties. It does not traverse the prototype chain, so the
671 // property must be found in the receiver for the stub to be 680 // property must be found in the receiver for the stub to be
672 // applicable. 681 // applicable.
673 if (lookup->holder() != *receiver) return NULL; 682 if (lookup->holder() != *receiver) return NULL;
674 maybe_code = StubCache::ComputeCallNormal(argc, 683 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc,
675 in_loop, 684 in_loop,
676 kind_, 685 kind_,
677 *name, 686 *name,
678 *receiver); 687 *receiver);
679 } 688 }
680 break; 689 break;
681 } 690 }
682 case INTERCEPTOR: { 691 case INTERCEPTOR: {
683 ASSERT(HasInterceptorGetter(lookup->holder())); 692 ASSERT(HasInterceptorGetter(lookup->holder()));
684 maybe_code = StubCache::ComputeCallInterceptor(argc, 693 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor(
685 kind_, 694 argc,
686 *name, 695 kind_,
687 *object, 696 *name,
688 lookup->holder()); 697 *object,
698 lookup->holder());
689 break; 699 break;
690 } 700 }
691 default: 701 default:
692 maybe_code = NULL; 702 maybe_code = NULL;
693 break; 703 break;
694 } 704 }
695 return maybe_code; 705 return maybe_code;
696 } 706 }
697 707
698 708
699 void CallICBase::UpdateCaches(LookupResult* lookup, 709 void CallICBase::UpdateCaches(LookupResult* lookup,
700 State state, 710 State state,
701 Code::ExtraICState extra_ic_state, 711 Code::ExtraICState extra_ic_state,
702 Handle<Object> object, 712 Handle<Object> object,
703 Handle<String> name) { 713 Handle<String> name) {
704 // Bail out if we didn't find a result. 714 // Bail out if we didn't find a result.
705 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 715 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
706 716
707 if (lookup->holder() != *object && 717 if (lookup->holder() != *object &&
708 HasNormalObjectsInPrototypeChain(lookup, object->GetPrototype())) { 718 HasNormalObjectsInPrototypeChain(
719 isolate(), lookup, object->GetPrototype())) {
709 // Suppress optimization for prototype chains with slow properties objects 720 // Suppress optimization for prototype chains with slow properties objects
710 // in the middle. 721 // in the middle.
711 return; 722 return;
712 } 723 }
713 724
714 // Compute the number of arguments. 725 // Compute the number of arguments.
715 int argc = target()->arguments_count(); 726 int argc = target()->arguments_count();
716 InLoopFlag in_loop = target()->ic_in_loop(); 727 InLoopFlag in_loop = target()->ic_in_loop();
717 MaybeObject* maybe_code = NULL; 728 MaybeObject* maybe_code = NULL;
718 bool had_proto_failure = false; 729 bool had_proto_failure = false;
719 if (state == UNINITIALIZED) { 730 if (state == UNINITIALIZED) {
720 // This is the first time we execute this inline cache. 731 // This is the first time we execute this inline cache.
721 // Set the target to the pre monomorphic stub to delay 732 // Set the target to the pre monomorphic stub to delay
722 // setting the monomorphic state. 733 // setting the monomorphic state.
723 maybe_code = StubCache::ComputeCallPreMonomorphic(argc, in_loop, kind_); 734 maybe_code = isolate()->stub_cache()->ComputeCallPreMonomorphic(argc,
735 in_loop,
736 kind_);
724 } else if (state == MONOMORPHIC) { 737 } else if (state == MONOMORPHIC) {
725 if (kind_ == Code::CALL_IC && 738 if (kind_ == Code::CALL_IC &&
726 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { 739 TryUpdateExtraICState(lookup, object, &extra_ic_state)) {
727 maybe_code = ComputeMonomorphicStub(lookup, 740 maybe_code = ComputeMonomorphicStub(lookup,
728 state, 741 state,
729 extra_ic_state, 742 extra_ic_state,
730 object, 743 object,
731 name); 744 name);
732 } else if (kind_ == Code::CALL_IC && 745 } else if (kind_ == Code::CALL_IC &&
733 TryRemoveInvalidPrototypeDependentStub(target(), 746 TryRemoveInvalidPrototypeDependentStub(target(),
734 *object, 747 *object,
735 *name)) { 748 *name)) {
736 had_proto_failure = true; 749 had_proto_failure = true;
737 maybe_code = ComputeMonomorphicStub(lookup, 750 maybe_code = ComputeMonomorphicStub(lookup,
738 state, 751 state,
739 extra_ic_state, 752 extra_ic_state,
740 object, 753 object,
741 name); 754 name);
742 } else { 755 } else {
743 maybe_code = StubCache::ComputeCallMegamorphic(argc, in_loop, kind_); 756 maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(argc,
757 in_loop,
758 kind_);
744 } 759 }
745 } else { 760 } else {
746 maybe_code = ComputeMonomorphicStub(lookup, 761 maybe_code = ComputeMonomorphicStub(lookup,
747 state, 762 state,
748 extra_ic_state, 763 extra_ic_state,
749 object, 764 object,
750 name); 765 name);
751 } 766 }
752 767
753 // If we're unable to compute the stub (not enough memory left), we 768 // If we're unable to compute the stub (not enough memory left), we
754 // simply avoid updating the caches. 769 // simply avoid updating the caches.
755 Object* code; 770 Object* code;
756 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; 771 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
757 772
758 // Patch the call site depending on the state of the cache. 773 // Patch the call site depending on the state of the cache.
759 if (state == UNINITIALIZED || 774 if (state == UNINITIALIZED ||
760 state == PREMONOMORPHIC || 775 state == PREMONOMORPHIC ||
761 state == MONOMORPHIC || 776 state == MONOMORPHIC ||
762 state == MONOMORPHIC_PROTOTYPE_FAILURE) { 777 state == MONOMORPHIC_PROTOTYPE_FAILURE) {
763 set_target(Code::cast(code)); 778 set_target(Code::cast(code));
764 } else if (state == MEGAMORPHIC) { 779 } else if (state == MEGAMORPHIC) {
765 // Cache code holding map should be consistent with 780 // Cache code holding map should be consistent with
766 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. 781 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
767 Map* map = JSObject::cast(object->IsJSObject() ? *object : 782 Map* map = JSObject::cast(object->IsJSObject() ? *object :
768 object->GetPrototype())->map(); 783 object->GetPrototype())->map();
769 784
770 // Update the stub cache. 785 // Update the stub cache.
771 StubCache::Set(*name, map, Code::cast(code)); 786 isolate()->stub_cache()->Set(*name, map, Code::cast(code));
772 } 787 }
773 788
774 USE(had_proto_failure); 789 USE(had_proto_failure);
775 #ifdef DEBUG 790 #ifdef DEBUG
776 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; 791 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
777 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", 792 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
778 name, state, target(), in_loop ? " (in-loop)" : ""); 793 name, state, target(), in_loop ? " (in-loop)" : "");
779 #endif 794 #endif
780 } 795 }
781 796
782 797
783 MaybeObject* KeyedCallIC::LoadFunction(State state, 798 MaybeObject* KeyedCallIC::LoadFunction(State state,
784 Handle<Object> object, 799 Handle<Object> object,
785 Handle<Object> key) { 800 Handle<Object> key) {
786 if (key->IsSymbol()) { 801 if (key->IsSymbol()) {
787 return CallICBase::LoadFunction(state, 802 return CallICBase::LoadFunction(state,
788 Code::kNoExtraICState, 803 Code::kNoExtraICState,
789 object, 804 object,
790 Handle<String>::cast(key)); 805 Handle<String>::cast(key));
791 } 806 }
792 807
793 if (object->IsUndefined() || object->IsNull()) { 808 if (object->IsUndefined() || object->IsNull()) {
794 return TypeError("non_object_property_call", object, key); 809 return TypeError("non_object_property_call", object, key);
795 } 810 }
796 811
797 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) { 812 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) {
798 int argc = target()->arguments_count(); 813 int argc = target()->arguments_count();
799 InLoopFlag in_loop = target()->ic_in_loop(); 814 InLoopFlag in_loop = target()->ic_in_loop();
800 MaybeObject* maybe_code = StubCache::ComputeCallMegamorphic( 815 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
801 argc, in_loop, Code::KEYED_CALL_IC); 816 argc, in_loop, Code::KEYED_CALL_IC);
802 Object* code; 817 Object* code;
803 if (maybe_code->ToObject(&code)) { 818 if (maybe_code->ToObject(&code)) {
804 set_target(Code::cast(code)); 819 set_target(Code::cast(code));
805 #ifdef DEBUG 820 #ifdef DEBUG
806 TraceIC( 821 TraceIC(
807 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); 822 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
808 #endif 823 #endif
809 } 824 }
810 } 825 }
811 826
812 HandleScope scope; 827 HandleScope scope(isolate());
813 Handle<Object> result = GetProperty(object, key); 828 Handle<Object> result = GetProperty(object, key);
814 RETURN_IF_EMPTY_HANDLE(result); 829 RETURN_IF_EMPTY_HANDLE(isolate(), result);
815 830
816 // Make receiver an object if the callee requires it. Strict mode or builtin 831 // Make receiver an object if the callee requires it. Strict mode or builtin
817 // functions do not wrap the receiver, non-strict functions and objects 832 // functions do not wrap the receiver, non-strict functions and objects
818 // called as functions do. 833 // called as functions do.
819 ReceiverToObjectIfRequired(result, object); 834 ReceiverToObjectIfRequired(result, object);
820 835
821 if (result->IsJSFunction()) return *result; 836 if (result->IsJSFunction()) return *result;
822 result = Handle<Object>(TryCallAsFunction(*result)); 837 result = Handle<Object>(TryCallAsFunction(*result));
823 if (result->IsJSFunction()) return *result; 838 if (result->IsJSFunction()) return *result;
824 839
(...skipping 20 matching lines...) Expand all
845 860
846 if (FLAG_use_ic) { 861 if (FLAG_use_ic) {
847 Code* non_monomorphic_stub = 862 Code* non_monomorphic_stub =
848 (state == UNINITIALIZED) ? pre_monomorphic_stub() : megamorphic_stub(); 863 (state == UNINITIALIZED) ? pre_monomorphic_stub() : megamorphic_stub();
849 864
850 // Use specialized code for getting the length of strings and 865 // Use specialized code for getting the length of strings and
851 // string wrapper objects. The length property of string wrapper 866 // string wrapper objects. The length property of string wrapper
852 // objects is read-only and therefore always returns the length of 867 // objects is read-only and therefore always returns the length of
853 // the underlying string value. See ECMA-262 15.5.5.1. 868 // the underlying string value. See ECMA-262 15.5.5.1.
854 if ((object->IsString() || object->IsStringWrapper()) && 869 if ((object->IsString() || object->IsStringWrapper()) &&
855 name->Equals(Heap::length_symbol())) { 870 name->Equals(isolate()->heap()->length_symbol())) {
856 HandleScope scope; 871 HandleScope scope(isolate());
857 #ifdef DEBUG 872 #ifdef DEBUG
858 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); 873 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
859 #endif 874 #endif
860 if (state == PREMONOMORPHIC) { 875 if (state == PREMONOMORPHIC) {
861 if (object->IsString()) { 876 if (object->IsString()) {
862 Map* map = HeapObject::cast(*object)->map(); 877 Map* map = HeapObject::cast(*object)->map();
863 const int offset = String::kLengthOffset; 878 const int offset = String::kLengthOffset;
864 PatchInlinedLoad(address(), map, offset); 879 PatchInlinedLoad(address(), map, offset);
865 set_target(Builtins::builtin(Builtins::LoadIC_StringLength)); 880 set_target(isolate()->builtins()->builtin(
881 Builtins::LoadIC_StringLength));
866 } else { 882 } else {
867 set_target(Builtins::builtin(Builtins::LoadIC_StringWrapperLength)); 883 set_target(isolate()->builtins()->builtin(
884 Builtins::LoadIC_StringWrapperLength));
868 } 885 }
869 } else if (state == MONOMORPHIC && object->IsStringWrapper()) { 886 } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
870 set_target(Builtins::builtin(Builtins::LoadIC_StringWrapperLength)); 887 set_target(isolate()->builtins()->builtin(
888 Builtins::LoadIC_StringWrapperLength));
871 } else { 889 } else {
872 set_target(non_monomorphic_stub); 890 set_target(non_monomorphic_stub);
873 } 891 }
874 // Get the string if we have a string wrapper object. 892 // Get the string if we have a string wrapper object.
875 if (object->IsJSValue()) { 893 if (object->IsJSValue()) {
876 object = Handle<Object>(Handle<JSValue>::cast(object)->value()); 894 object = Handle<Object>(Handle<JSValue>::cast(object)->value(),
895 isolate());
877 } 896 }
878 return Smi::FromInt(String::cast(*object)->length()); 897 return Smi::FromInt(String::cast(*object)->length());
879 } 898 }
880 899
881 // Use specialized code for getting the length of arrays. 900 // Use specialized code for getting the length of arrays.
882 if (object->IsJSArray() && name->Equals(Heap::length_symbol())) { 901 if (object->IsJSArray() &&
902 name->Equals(isolate()->heap()->length_symbol())) {
883 #ifdef DEBUG 903 #ifdef DEBUG
884 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); 904 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
885 #endif 905 #endif
886 if (state == PREMONOMORPHIC) { 906 if (state == PREMONOMORPHIC) {
887 Map* map = HeapObject::cast(*object)->map(); 907 Map* map = HeapObject::cast(*object)->map();
888 const int offset = JSArray::kLengthOffset; 908 const int offset = JSArray::kLengthOffset;
889 PatchInlinedLoad(address(), map, offset); 909 PatchInlinedLoad(address(), map, offset);
890 set_target(Builtins::builtin(Builtins::LoadIC_ArrayLength)); 910 set_target(isolate()->builtins()->builtin(
911 Builtins::LoadIC_ArrayLength));
891 } else { 912 } else {
892 set_target(non_monomorphic_stub); 913 set_target(non_monomorphic_stub);
893 } 914 }
894 return JSArray::cast(*object)->length(); 915 return JSArray::cast(*object)->length();
895 } 916 }
896 917
897 // Use specialized code for getting prototype of functions. 918 // Use specialized code for getting prototype of functions.
898 if (object->IsJSFunction() && name->Equals(Heap::prototype_symbol()) && 919 if (object->IsJSFunction() &&
920 name->Equals(isolate()->heap()->prototype_symbol()) &&
899 JSFunction::cast(*object)->should_have_prototype()) { 921 JSFunction::cast(*object)->should_have_prototype()) {
900 #ifdef DEBUG 922 #ifdef DEBUG
901 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); 923 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
902 #endif 924 #endif
903 if (state == PREMONOMORPHIC) { 925 if (state == PREMONOMORPHIC) {
904 set_target(Builtins::builtin(Builtins::LoadIC_FunctionPrototype)); 926 set_target(isolate()->builtins()->builtin(
927 Builtins::LoadIC_FunctionPrototype));
905 } else { 928 } else {
906 set_target(non_monomorphic_stub); 929 set_target(non_monomorphic_stub);
907 } 930 }
908 return Accessors::FunctionGetPrototype(*object, 0); 931 return Accessors::FunctionGetPrototype(*object, 0);
909 } 932 }
910 } 933 }
911 934
912 // Check if the name is trivially convertible to an index and get 935 // Check if the name is trivially convertible to an index and get
913 // the element if so. 936 // the element if so.
914 uint32_t index; 937 uint32_t index;
915 if (name->AsArrayIndex(&index)) return object->GetElement(index); 938 if (name->AsArrayIndex(&index)) return object->GetElement(index);
916 939
917 // Named lookup in the object. 940 // Named lookup in the object.
918 LookupResult lookup; 941 LookupResult lookup;
919 LookupForRead(*object, *name, &lookup); 942 LookupForRead(*object, *name, &lookup);
920 943
921 // If we did not find a property, check if we need to throw an exception. 944 // If we did not find a property, check if we need to throw an exception.
922 if (!lookup.IsProperty()) { 945 if (!lookup.IsProperty()) {
923 if (FLAG_strict || IsContextual(object)) { 946 if (FLAG_strict || IsContextual(object)) {
924 return ReferenceError("not_defined", name); 947 return ReferenceError("not_defined", name);
925 } 948 }
926 LOG(SuspectReadEvent(*name, *object)); 949 LOG(isolate(), SuspectReadEvent(*name, *object));
927 } 950 }
928 951
929 bool can_be_inlined_precheck = 952 bool can_be_inlined_precheck =
930 FLAG_use_ic && 953 FLAG_use_ic &&
931 lookup.IsProperty() && 954 lookup.IsProperty() &&
932 lookup.IsCacheable() && 955 lookup.IsCacheable() &&
933 lookup.holder() == *object && 956 lookup.holder() == *object &&
934 !object->IsAccessCheckNeeded(); 957 !object->IsAccessCheckNeeded();
935 958
936 bool can_be_inlined = 959 bool can_be_inlined =
(...skipping 30 matching lines...) Expand all
967 Map* map = lookup.holder()->map(); 990 Map* map = lookup.holder()->map();
968 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast( 991 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(
969 lookup.holder()->property_dictionary()->ValueAt( 992 lookup.holder()->property_dictionary()->ValueAt(
970 lookup.GetDictionaryEntry())); 993 lookup.GetDictionaryEntry()));
971 if (PatchInlinedContextualLoad(address(), 994 if (PatchInlinedContextualLoad(address(),
972 map, 995 map,
973 cell, 996 cell,
974 lookup.IsDontDelete())) { 997 lookup.IsDontDelete())) {
975 set_target(megamorphic_stub()); 998 set_target(megamorphic_stub());
976 TRACE_IC_NAMED("[LoadIC : inline contextual patch %s]\n", name); 999 TRACE_IC_NAMED("[LoadIC : inline contextual patch %s]\n", name);
977 ASSERT(cell->value() != Heap::the_hole_value()); 1000 ASSERT(cell->value() != isolate()->heap()->the_hole_value());
978 return cell->value(); 1001 return cell->value();
979 } 1002 }
980 } else { 1003 } else {
981 if (FLAG_use_ic && state == PREMONOMORPHIC) { 1004 if (FLAG_use_ic && state == PREMONOMORPHIC) {
982 TRACE_IC_NAMED("[LoadIC : no inline patch %s (not inlinable)]\n", name); 1005 TRACE_IC_NAMED("[LoadIC : no inline patch %s (not inlinable)]\n", name);
983 } 1006 }
984 } 1007 }
985 1008
986 // Update inline cache and stub cache. 1009 // Update inline cache and stub cache.
987 if (FLAG_use_ic) { 1010 if (FLAG_use_ic) {
(...skipping 26 matching lines...) Expand all
1014 Handle<Object> object, 1037 Handle<Object> object,
1015 Handle<String> name) { 1038 Handle<String> name) {
1016 // Bail out if the result is not cacheable. 1039 // Bail out if the result is not cacheable.
1017 if (!lookup->IsCacheable()) return; 1040 if (!lookup->IsCacheable()) return;
1018 1041
1019 // Loading properties from values is not common, so don't try to 1042 // Loading properties from values is not common, so don't try to
1020 // deal with non-JS objects here. 1043 // deal with non-JS objects here.
1021 if (!object->IsJSObject()) return; 1044 if (!object->IsJSObject()) return;
1022 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1045 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1023 1046
1024 if (HasNormalObjectsInPrototypeChain(lookup, *object)) return; 1047 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
1025 1048
1026 // Compute the code stub for this load. 1049 // Compute the code stub for this load.
1027 MaybeObject* maybe_code = NULL; 1050 MaybeObject* maybe_code = NULL;
1028 Object* code; 1051 Object* code;
1029 if (state == UNINITIALIZED) { 1052 if (state == UNINITIALIZED) {
1030 // This is the first time we execute this inline cache. 1053 // This is the first time we execute this inline cache.
1031 // Set the target to the pre monomorphic stub to delay 1054 // Set the target to the pre monomorphic stub to delay
1032 // setting the monomorphic state. 1055 // setting the monomorphic state.
1033 maybe_code = pre_monomorphic_stub(); 1056 maybe_code = pre_monomorphic_stub();
1034 } else if (!lookup->IsProperty()) { 1057 } else if (!lookup->IsProperty()) {
1035 // Nonexistent property. The result is undefined. 1058 // Nonexistent property. The result is undefined.
1036 maybe_code = StubCache::ComputeLoadNonexistent(*name, *receiver); 1059 maybe_code = isolate()->stub_cache()->ComputeLoadNonexistent(*name,
1060 *receiver);
1037 } else { 1061 } else {
1038 // Compute monomorphic stub. 1062 // Compute monomorphic stub.
1039 switch (lookup->type()) { 1063 switch (lookup->type()) {
1040 case FIELD: { 1064 case FIELD: {
1041 maybe_code = StubCache::ComputeLoadField(*name, *receiver, 1065 maybe_code = isolate()->stub_cache()->ComputeLoadField(
1042 lookup->holder(), 1066 *name,
1043 lookup->GetFieldIndex()); 1067 *receiver,
1068 lookup->holder(),
1069 lookup->GetFieldIndex());
1044 break; 1070 break;
1045 } 1071 }
1046 case CONSTANT_FUNCTION: { 1072 case CONSTANT_FUNCTION: {
1047 Object* constant = lookup->GetConstantFunction(); 1073 Object* constant = lookup->GetConstantFunction();
1048 maybe_code = StubCache::ComputeLoadConstant(*name, *receiver, 1074 maybe_code = isolate()->stub_cache()->ComputeLoadConstant(
1049 lookup->holder(), constant); 1075 *name, *receiver, lookup->holder(), constant);
1050 break; 1076 break;
1051 } 1077 }
1052 case NORMAL: { 1078 case NORMAL: {
1053 if (lookup->holder()->IsGlobalObject()) { 1079 if (lookup->holder()->IsGlobalObject()) {
1054 GlobalObject* global = GlobalObject::cast(lookup->holder()); 1080 GlobalObject* global = GlobalObject::cast(lookup->holder());
1055 JSGlobalPropertyCell* cell = 1081 JSGlobalPropertyCell* cell =
1056 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 1082 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
1057 maybe_code = StubCache::ComputeLoadGlobal(*name, 1083 maybe_code = isolate()->stub_cache()->ComputeLoadGlobal(*name,
1058 *receiver, 1084 *receiver,
1059 global, 1085 global,
1060 cell, 1086 cell,
1061 lookup->IsDontDelete()); 1087 lookup->IsDontDelete());
1062 } else { 1088 } else {
1063 // There is only one shared stub for loading normalized 1089 // There is only one shared stub for loading normalized
1064 // properties. It does not traverse the prototype chain, so the 1090 // properties. It does not traverse the prototype chain, so the
1065 // property must be found in the receiver for the stub to be 1091 // property must be found in the receiver for the stub to be
1066 // applicable. 1092 // applicable.
1067 if (lookup->holder() != *receiver) return; 1093 if (lookup->holder() != *receiver) return;
1068 maybe_code = StubCache::ComputeLoadNormal(); 1094 maybe_code = isolate()->stub_cache()->ComputeLoadNormal();
1069 } 1095 }
1070 break; 1096 break;
1071 } 1097 }
1072 case CALLBACKS: { 1098 case CALLBACKS: {
1073 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; 1099 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return;
1074 AccessorInfo* callback = 1100 AccessorInfo* callback =
1075 AccessorInfo::cast(lookup->GetCallbackObject()); 1101 AccessorInfo::cast(lookup->GetCallbackObject());
1076 if (v8::ToCData<Address>(callback->getter()) == 0) return; 1102 if (v8::ToCData<Address>(callback->getter()) == 0) return;
1077 maybe_code = StubCache::ComputeLoadCallback(*name, *receiver, 1103 maybe_code = isolate()->stub_cache()->ComputeLoadCallback(
1078 lookup->holder(), callback); 1104 *name, *receiver, lookup->holder(), callback);
1079 break; 1105 break;
1080 } 1106 }
1081 case INTERCEPTOR: { 1107 case INTERCEPTOR: {
1082 ASSERT(HasInterceptorGetter(lookup->holder())); 1108 ASSERT(HasInterceptorGetter(lookup->holder()));
1083 maybe_code = StubCache::ComputeLoadInterceptor(*name, *receiver, 1109 maybe_code = isolate()->stub_cache()->ComputeLoadInterceptor(
1084 lookup->holder()); 1110 *name, *receiver, lookup->holder());
1085 break; 1111 break;
1086 } 1112 }
1087 default: 1113 default:
1088 return; 1114 return;
1089 } 1115 }
1090 } 1116 }
1091 1117
1092 // If we're unable to compute the stub (not enough memory left), we 1118 // If we're unable to compute the stub (not enough memory left), we
1093 // simply avoid updating the caches. 1119 // simply avoid updating the caches.
1094 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; 1120 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
1095 1121
1096 // Patch the call site depending on the state of the cache. 1122 // Patch the call site depending on the state of the cache.
1097 if (state == UNINITIALIZED || state == PREMONOMORPHIC || 1123 if (state == UNINITIALIZED || state == PREMONOMORPHIC ||
1098 state == MONOMORPHIC_PROTOTYPE_FAILURE) { 1124 state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1099 set_target(Code::cast(code)); 1125 set_target(Code::cast(code));
1100 } else if (state == MONOMORPHIC) { 1126 } else if (state == MONOMORPHIC) {
1101 set_target(megamorphic_stub()); 1127 set_target(megamorphic_stub());
1102 } else if (state == MEGAMORPHIC) { 1128 } else if (state == MEGAMORPHIC) {
1103 // Cache code holding map should be consistent with 1129 // Cache code holding map should be consistent with
1104 // GenerateMonomorphicCacheProbe. 1130 // GenerateMonomorphicCacheProbe.
1105 Map* map = JSObject::cast(object->IsJSObject() ? *object : 1131 Map* map = JSObject::cast(object->IsJSObject() ? *object :
1106 object->GetPrototype())->map(); 1132 object->GetPrototype())->map();
1107 1133
1108 StubCache::Set(*name, map, Code::cast(code)); 1134 isolate()->stub_cache()->Set(*name, map, Code::cast(code));
1109 } 1135 }
1110 1136
1111 #ifdef DEBUG 1137 #ifdef DEBUG
1112 TraceIC("LoadIC", name, state, target()); 1138 TraceIC("LoadIC", name, state, target());
1113 #endif 1139 #endif
1114 } 1140 }
1115 1141
1116 1142
1117 MaybeObject* KeyedLoadIC::Load(State state, 1143 MaybeObject* KeyedLoadIC::Load(State state,
1118 Handle<Object> object, 1144 Handle<Object> object,
1119 Handle<Object> key) { 1145 Handle<Object> key) {
1120 if (key->IsSymbol()) { 1146 if (key->IsSymbol()) {
1121 Handle<String> name = Handle<String>::cast(key); 1147 Handle<String> name = Handle<String>::cast(key);
1122 1148
1123 // If the object is undefined or null it's illegal to try to get any 1149 // If the object is undefined or null it's illegal to try to get any
1124 // of its properties; throw a TypeError in that case. 1150 // of its properties; throw a TypeError in that case.
1125 if (object->IsUndefined() || object->IsNull()) { 1151 if (object->IsUndefined() || object->IsNull()) {
1126 return TypeError("non_object_property_load", object, name); 1152 return TypeError("non_object_property_load", object, name);
1127 } 1153 }
1128 1154
1129 if (FLAG_use_ic) { 1155 if (FLAG_use_ic) {
1130 // TODO(1073): don't ignore the current stub state. 1156 // TODO(1073): don't ignore the current stub state.
1131 1157
1132 // Use specialized code for getting the length of strings. 1158 // Use specialized code for getting the length of strings.
1133 if (object->IsString() && name->Equals(Heap::length_symbol())) { 1159 if (object->IsString() &&
1160 name->Equals(isolate()->heap()->length_symbol())) {
1134 Handle<String> string = Handle<String>::cast(object); 1161 Handle<String> string = Handle<String>::cast(object);
1135 Object* code = NULL; 1162 Object* code = NULL;
1136 { MaybeObject* maybe_code = 1163 { MaybeObject* maybe_code =
1137 StubCache::ComputeKeyedLoadStringLength(*name, *string); 1164 isolate()->stub_cache()->ComputeKeyedLoadStringLength(*name,
1165 *string);
1138 if (!maybe_code->ToObject(&code)) return maybe_code; 1166 if (!maybe_code->ToObject(&code)) return maybe_code;
1139 } 1167 }
1140 set_target(Code::cast(code)); 1168 set_target(Code::cast(code));
1141 #ifdef DEBUG 1169 #ifdef DEBUG
1142 TraceIC("KeyedLoadIC", name, state, target()); 1170 TraceIC("KeyedLoadIC", name, state, target());
1143 #endif // DEBUG 1171 #endif // DEBUG
1144 return Smi::FromInt(string->length()); 1172 return Smi::FromInt(string->length());
1145 } 1173 }
1146 1174
1147 // Use specialized code for getting the length of arrays. 1175 // Use specialized code for getting the length of arrays.
1148 if (object->IsJSArray() && name->Equals(Heap::length_symbol())) { 1176 if (object->IsJSArray() &&
1177 name->Equals(isolate()->heap()->length_symbol())) {
1149 Handle<JSArray> array = Handle<JSArray>::cast(object); 1178 Handle<JSArray> array = Handle<JSArray>::cast(object);
1150 Object* code; 1179 Object* code;
1151 { MaybeObject* maybe_code = 1180 { MaybeObject* maybe_code =
1152 StubCache::ComputeKeyedLoadArrayLength(*name, *array); 1181 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(*name,
1182 *array);
1153 if (!maybe_code->ToObject(&code)) return maybe_code; 1183 if (!maybe_code->ToObject(&code)) return maybe_code;
1154 } 1184 }
1155 set_target(Code::cast(code)); 1185 set_target(Code::cast(code));
1156 #ifdef DEBUG 1186 #ifdef DEBUG
1157 TraceIC("KeyedLoadIC", name, state, target()); 1187 TraceIC("KeyedLoadIC", name, state, target());
1158 #endif // DEBUG 1188 #endif // DEBUG
1159 return JSArray::cast(*object)->length(); 1189 return JSArray::cast(*object)->length();
1160 } 1190 }
1161 1191
1162 // Use specialized code for getting prototype of functions. 1192 // Use specialized code for getting prototype of functions.
1163 if (object->IsJSFunction() && name->Equals(Heap::prototype_symbol()) && 1193 if (object->IsJSFunction() &&
1194 name->Equals(isolate()->heap()->prototype_symbol()) &&
1164 JSFunction::cast(*object)->should_have_prototype()) { 1195 JSFunction::cast(*object)->should_have_prototype()) {
1165 Handle<JSFunction> function = Handle<JSFunction>::cast(object); 1196 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
1166 Object* code; 1197 Object* code;
1167 { MaybeObject* maybe_code = 1198 { MaybeObject* maybe_code =
1168 StubCache::ComputeKeyedLoadFunctionPrototype(*name, *function); 1199 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype(
1200 *name, *function);
1169 if (!maybe_code->ToObject(&code)) return maybe_code; 1201 if (!maybe_code->ToObject(&code)) return maybe_code;
1170 } 1202 }
1171 set_target(Code::cast(code)); 1203 set_target(Code::cast(code));
1172 #ifdef DEBUG 1204 #ifdef DEBUG
1173 TraceIC("KeyedLoadIC", name, state, target()); 1205 TraceIC("KeyedLoadIC", name, state, target());
1174 #endif // DEBUG 1206 #endif // DEBUG
1175 return Accessors::FunctionGetPrototype(*object, 0); 1207 return Accessors::FunctionGetPrototype(*object, 0);
1176 } 1208 }
1177 } 1209 }
1178 1210
1179 // Check if the name is trivially convertible to an index and get 1211 // Check if the name is trivially convertible to an index and get
1180 // the element or char if so. 1212 // the element or char if so.
1181 uint32_t index = 0; 1213 uint32_t index = 0;
1182 if (name->AsArrayIndex(&index)) { 1214 if (name->AsArrayIndex(&index)) {
1183 HandleScope scope; 1215 HandleScope scope(isolate());
1184 // Rewrite to the generic keyed load stub. 1216 // Rewrite to the generic keyed load stub.
1185 if (FLAG_use_ic) set_target(generic_stub()); 1217 if (FLAG_use_ic) set_target(generic_stub());
1186 return Runtime::GetElementOrCharAt(object, index); 1218 return Runtime::GetElementOrCharAt(isolate(), object, index);
1187 } 1219 }
1188 1220
1189 // Named lookup. 1221 // Named lookup.
1190 LookupResult lookup; 1222 LookupResult lookup;
1191 LookupForRead(*object, *name, &lookup); 1223 LookupForRead(*object, *name, &lookup);
1192 1224
1193 // If we did not find a property, check if we need to throw an exception. 1225 // If we did not find a property, check if we need to throw an exception.
1194 if (!lookup.IsProperty()) { 1226 if (!lookup.IsProperty()) {
1195 if (FLAG_strict || IsContextual(object)) { 1227 if (FLAG_strict || IsContextual(object)) {
1196 return ReferenceError("not_defined", name); 1228 return ReferenceError("not_defined", name);
(...skipping 29 matching lines...) Expand all
1226 1258
1227 if (use_ic) { 1259 if (use_ic) {
1228 Code* stub = generic_stub(); 1260 Code* stub = generic_stub();
1229 if (state == UNINITIALIZED) { 1261 if (state == UNINITIALIZED) {
1230 if (object->IsString() && key->IsNumber()) { 1262 if (object->IsString() && key->IsNumber()) {
1231 stub = string_stub(); 1263 stub = string_stub();
1232 } else if (object->IsJSObject()) { 1264 } else if (object->IsJSObject()) {
1233 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1265 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1234 if (receiver->HasExternalArrayElements()) { 1266 if (receiver->HasExternalArrayElements()) {
1235 MaybeObject* probe = 1267 MaybeObject* probe =
1236 StubCache::ComputeKeyedLoadOrStoreExternalArray(*receiver, 1268 isolate()->stub_cache()->ComputeKeyedLoadOrStoreExternalArray(
1237 false, 1269 *receiver, false, kNonStrictMode);
1238 kNonStrictMode);
1239 stub = probe->IsFailure() ? 1270 stub = probe->IsFailure() ?
1240 NULL : Code::cast(probe->ToObjectUnchecked()); 1271 NULL : Code::cast(probe->ToObjectUnchecked());
1241 } else if (receiver->HasIndexedInterceptor()) { 1272 } else if (receiver->HasIndexedInterceptor()) {
1242 stub = indexed_interceptor_stub(); 1273 stub = indexed_interceptor_stub();
1243 } else if (key->IsSmi() && 1274 } else if (key->IsSmi() &&
1244 receiver->map()->has_fast_elements()) { 1275 receiver->map()->has_fast_elements()) {
1245 MaybeObject* probe = 1276 MaybeObject* probe =
1246 StubCache::ComputeKeyedLoadSpecialized(*receiver); 1277 isolate()->stub_cache()->ComputeKeyedLoadSpecialized(*receiver);
1247 stub = probe->IsFailure() ? 1278 stub = probe->IsFailure() ?
1248 NULL : Code::cast(probe->ToObjectUnchecked()); 1279 NULL : Code::cast(probe->ToObjectUnchecked());
1249 } 1280 }
1250 } 1281 }
1251 } 1282 }
1252 if (stub != NULL) set_target(stub); 1283 if (stub != NULL) set_target(stub);
1253 1284
1254 #ifdef DEBUG 1285 #ifdef DEBUG
1255 TraceIC("KeyedLoadIC", key, state, target()); 1286 TraceIC("KeyedLoadIC", key, state, target());
1256 #endif // DEBUG 1287 #endif // DEBUG
1257 1288
1258 // For JSObjects with fast elements that are not value wrappers 1289 // For JSObjects with fast elements that are not value wrappers
1259 // and that do not have indexed interceptors, we initialize the 1290 // and that do not have indexed interceptors, we initialize the
1260 // inlined fast case (if present) by patching the inlined map 1291 // inlined fast case (if present) by patching the inlined map
1261 // check. 1292 // check.
1262 if (object->IsJSObject() && 1293 if (object->IsJSObject() &&
1263 !object->IsJSValue() && 1294 !object->IsJSValue() &&
1264 !JSObject::cast(*object)->HasIndexedInterceptor() && 1295 !JSObject::cast(*object)->HasIndexedInterceptor() &&
1265 JSObject::cast(*object)->HasFastElements()) { 1296 JSObject::cast(*object)->HasFastElements()) {
1266 Map* map = JSObject::cast(*object)->map(); 1297 Map* map = JSObject::cast(*object)->map();
1267 PatchInlinedLoad(address(), map); 1298 PatchInlinedLoad(address(), map);
1268 } 1299 }
1269 } 1300 }
1270 1301
1271 // Get the property. 1302 // Get the property.
1272 return Runtime::GetObjectProperty(object, key); 1303 return Runtime::GetObjectProperty(isolate(), object, key);
1273 } 1304 }
1274 1305
1275 1306
1276 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, 1307 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state,
1277 Handle<Object> object, Handle<String> name) { 1308 Handle<Object> object, Handle<String> name) {
1278 // Bail out if we didn't find a result. 1309 // Bail out if we didn't find a result.
1279 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 1310 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
1280 1311
1281 if (!object->IsJSObject()) return; 1312 if (!object->IsJSObject()) return;
1282 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1313 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1283 1314
1284 if (HasNormalObjectsInPrototypeChain(lookup, *object)) return; 1315 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
1285 1316
1286 // Compute the code stub for this load. 1317 // Compute the code stub for this load.
1287 MaybeObject* maybe_code = NULL; 1318 MaybeObject* maybe_code = NULL;
1288 Object* code; 1319 Object* code;
1289 1320
1290 if (state == UNINITIALIZED) { 1321 if (state == UNINITIALIZED) {
1291 // This is the first time we execute this inline cache. 1322 // This is the first time we execute this inline cache.
1292 // Set the target to the pre monomorphic stub to delay 1323 // Set the target to the pre monomorphic stub to delay
1293 // setting the monomorphic state. 1324 // setting the monomorphic state.
1294 maybe_code = pre_monomorphic_stub(); 1325 maybe_code = pre_monomorphic_stub();
1295 } else { 1326 } else {
1296 // Compute a monomorphic stub. 1327 // Compute a monomorphic stub.
1297 switch (lookup->type()) { 1328 switch (lookup->type()) {
1298 case FIELD: { 1329 case FIELD: {
1299 maybe_code = StubCache::ComputeKeyedLoadField(*name, *receiver, 1330 maybe_code = isolate()->stub_cache()->ComputeKeyedLoadField(
1300 lookup->holder(), 1331 *name, *receiver, lookup->holder(), lookup->GetFieldIndex());
1301 lookup->GetFieldIndex());
1302 break; 1332 break;
1303 } 1333 }
1304 case CONSTANT_FUNCTION: { 1334 case CONSTANT_FUNCTION: {
1305 Object* constant = lookup->GetConstantFunction(); 1335 Object* constant = lookup->GetConstantFunction();
1306 maybe_code = StubCache::ComputeKeyedLoadConstant(*name, 1336 maybe_code = isolate()->stub_cache()->ComputeKeyedLoadConstant(
1307 *receiver, 1337 *name, *receiver, lookup->holder(), constant);
1308 lookup->holder(),
1309 constant);
1310 break; 1338 break;
1311 } 1339 }
1312 case CALLBACKS: { 1340 case CALLBACKS: {
1313 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; 1341 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return;
1314 AccessorInfo* callback = 1342 AccessorInfo* callback =
1315 AccessorInfo::cast(lookup->GetCallbackObject()); 1343 AccessorInfo::cast(lookup->GetCallbackObject());
1316 if (v8::ToCData<Address>(callback->getter()) == 0) return; 1344 if (v8::ToCData<Address>(callback->getter()) == 0) return;
1317 maybe_code = StubCache::ComputeKeyedLoadCallback(*name, 1345 maybe_code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
1318 *receiver, 1346 *name, *receiver, lookup->holder(), callback);
1319 lookup->holder(),
1320 callback);
1321 break; 1347 break;
1322 } 1348 }
1323 case INTERCEPTOR: { 1349 case INTERCEPTOR: {
1324 ASSERT(HasInterceptorGetter(lookup->holder())); 1350 ASSERT(HasInterceptorGetter(lookup->holder()));
1325 maybe_code = StubCache::ComputeKeyedLoadInterceptor(*name, *receiver, 1351 maybe_code = isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
1326 lookup->holder()); 1352 *name, *receiver, lookup->holder());
1327 break; 1353 break;
1328 } 1354 }
1329 default: { 1355 default: {
1330 // Always rewrite to the generic case so that we do not 1356 // Always rewrite to the generic case so that we do not
1331 // repeatedly try to rewrite. 1357 // repeatedly try to rewrite.
1332 maybe_code = generic_stub(); 1358 maybe_code = generic_stub();
1333 break; 1359 break;
1334 } 1360 }
1335 } 1361 }
1336 } 1362 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 Handle<Object> value) { 1418 Handle<Object> value) {
1393 // If the object is undefined or null it's illegal to try to set any 1419 // If the object is undefined or null it's illegal to try to set any
1394 // properties on it; throw a TypeError in that case. 1420 // properties on it; throw a TypeError in that case.
1395 if (object->IsUndefined() || object->IsNull()) { 1421 if (object->IsUndefined() || object->IsNull()) {
1396 return TypeError("non_object_property_store", object, name); 1422 return TypeError("non_object_property_store", object, name);
1397 } 1423 }
1398 1424
1399 if (!object->IsJSObject()) { 1425 if (!object->IsJSObject()) {
1400 // The length property of string values is read-only. Throw in strict mode. 1426 // The length property of string values is read-only. Throw in strict mode.
1401 if (strict_mode == kStrictMode && object->IsString() && 1427 if (strict_mode == kStrictMode && object->IsString() &&
1402 name->Equals(Heap::length_symbol())) { 1428 name->Equals(isolate()->heap()->length_symbol())) {
1403 return TypeError("strict_read_only_property", object, name); 1429 return TypeError("strict_read_only_property", object, name);
1404 } 1430 }
1405 // Ignore stores where the receiver is not a JSObject. 1431 // Ignore stores where the receiver is not a JSObject.
1406 return *value; 1432 return *value;
1407 } 1433 }
1408 1434
1409 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1435 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1410 1436
1411 // Check if the given name is an array index. 1437 // Check if the given name is an array index.
1412 uint32_t index; 1438 uint32_t index;
1413 if (name->AsArrayIndex(&index)) { 1439 if (name->AsArrayIndex(&index)) {
1414 HandleScope scope; 1440 HandleScope scope(isolate());
1415 Handle<Object> result = SetElement(receiver, index, value, strict_mode); 1441 Handle<Object> result = SetElement(receiver, index, value, strict_mode);
1416 if (result.is_null()) return Failure::Exception(); 1442 if (result.is_null()) return Failure::Exception();
1417 return *value; 1443 return *value;
1418 } 1444 }
1419 1445
1420 // Use specialized code for setting the length of arrays. 1446 // Use specialized code for setting the length of arrays.
1421 if (receiver->IsJSArray() 1447 if (receiver->IsJSArray()
1422 && name->Equals(Heap::length_symbol()) 1448 && name->Equals(isolate()->heap()->length_symbol())
1423 && receiver->AllowsSetElementsLength()) { 1449 && receiver->AllowsSetElementsLength()) {
1424 #ifdef DEBUG 1450 #ifdef DEBUG
1425 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); 1451 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
1426 #endif 1452 #endif
1427 Builtins::Name target = (strict_mode == kStrictMode) 1453 Builtins::Name target = (strict_mode == kStrictMode)
1428 ? Builtins::StoreIC_ArrayLength_Strict 1454 ? Builtins::StoreIC_ArrayLength_Strict
1429 : Builtins::StoreIC_ArrayLength; 1455 : Builtins::StoreIC_ArrayLength;
1430 set_target(Builtins::builtin(target)); 1456 set_target(isolate()->builtins()->builtin(target));
1431 return receiver->SetProperty(*name, *value, NONE, strict_mode); 1457 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1432 } 1458 }
1433 1459
1434 // Lookup the property locally in the receiver. 1460 // Lookup the property locally in the receiver.
1435 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { 1461 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1436 LookupResult lookup; 1462 LookupResult lookup;
1437 1463
1438 if (LookupForWrite(*receiver, *name, &lookup)) { 1464 if (LookupForWrite(*receiver, *name, &lookup)) {
1439 bool can_be_inlined = 1465 bool can_be_inlined =
1440 state == UNINITIALIZED && 1466 state == UNINITIALIZED &&
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 // current state. 1562 // current state.
1537 PropertyType type = lookup->type(); 1563 PropertyType type = lookup->type();
1538 1564
1539 // Compute the code stub for this store; used for rewriting to 1565 // Compute the code stub for this store; used for rewriting to
1540 // monomorphic state and making sure that the code stub is in the 1566 // monomorphic state and making sure that the code stub is in the
1541 // stub cache. 1567 // stub cache.
1542 MaybeObject* maybe_code = NULL; 1568 MaybeObject* maybe_code = NULL;
1543 Object* code = NULL; 1569 Object* code = NULL;
1544 switch (type) { 1570 switch (type) {
1545 case FIELD: { 1571 case FIELD: {
1546 maybe_code = StubCache::ComputeStoreField( 1572 maybe_code = isolate()->stub_cache()->ComputeStoreField(
1547 *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode); 1573 *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode);
1548 break; 1574 break;
1549 } 1575 }
1550 case MAP_TRANSITION: { 1576 case MAP_TRANSITION: {
1551 if (lookup->GetAttributes() != NONE) return; 1577 if (lookup->GetAttributes() != NONE) return;
1552 HandleScope scope; 1578 HandleScope scope(isolate());
1553 ASSERT(type == MAP_TRANSITION); 1579 ASSERT(type == MAP_TRANSITION);
1554 Handle<Map> transition(lookup->GetTransitionMap()); 1580 Handle<Map> transition(lookup->GetTransitionMap());
1555 int index = transition->PropertyIndexFor(*name); 1581 int index = transition->PropertyIndexFor(*name);
1556 maybe_code = StubCache::ComputeStoreField( 1582 maybe_code = isolate()->stub_cache()->ComputeStoreField(
1557 *name, *receiver, index, *transition, strict_mode); 1583 *name, *receiver, index, *transition, strict_mode);
1558 break; 1584 break;
1559 } 1585 }
1560 case NORMAL: { 1586 case NORMAL: {
1561 if (receiver->IsGlobalObject()) { 1587 if (receiver->IsGlobalObject()) {
1562 // The stub generated for the global object picks the value directly 1588 // The stub generated for the global object picks the value directly
1563 // from the property cell. So the property must be directly on the 1589 // from the property cell. So the property must be directly on the
1564 // global object. 1590 // global object.
1565 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1591 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1566 JSGlobalPropertyCell* cell = 1592 JSGlobalPropertyCell* cell =
1567 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 1593 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
1568 maybe_code = StubCache::ComputeStoreGlobal( 1594 maybe_code = isolate()->stub_cache()->ComputeStoreGlobal(
1569 *name, *global, cell, strict_mode); 1595 *name, *global, cell, strict_mode);
1570 } else { 1596 } else {
1571 if (lookup->holder() != *receiver) return; 1597 if (lookup->holder() != *receiver) return;
1572 maybe_code = StubCache::ComputeStoreNormal(strict_mode); 1598 maybe_code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
1573 } 1599 }
1574 break; 1600 break;
1575 } 1601 }
1576 case CALLBACKS: { 1602 case CALLBACKS: {
1577 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; 1603 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return;
1578 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1604 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
1579 if (v8::ToCData<Address>(callback->setter()) == 0) return; 1605 if (v8::ToCData<Address>(callback->setter()) == 0) return;
1580 maybe_code = StubCache::ComputeStoreCallback( 1606 maybe_code = isolate()->stub_cache()->ComputeStoreCallback(
1581 *name, *receiver, callback, strict_mode); 1607 *name, *receiver, callback, strict_mode);
1582 break; 1608 break;
1583 } 1609 }
1584 case INTERCEPTOR: { 1610 case INTERCEPTOR: {
1585 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); 1611 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
1586 maybe_code = StubCache::ComputeStoreInterceptor( 1612 maybe_code = isolate()->stub_cache()->ComputeStoreInterceptor(
1587 *name, *receiver, strict_mode); 1613 *name, *receiver, strict_mode);
1588 break; 1614 break;
1589 } 1615 }
1590 default: 1616 default:
1591 return; 1617 return;
1592 } 1618 }
1593 1619
1594 // If we're unable to compute the stub (not enough memory left), we 1620 // If we're unable to compute the stub (not enough memory left), we
1595 // simply avoid updating the caches. 1621 // simply avoid updating the caches.
1596 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; 1622 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
1597 1623
1598 // Patch the call site depending on the state of the cache. 1624 // Patch the call site depending on the state of the cache.
1599 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { 1625 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1600 set_target(Code::cast(code)); 1626 set_target(Code::cast(code));
1601 } else if (state == MONOMORPHIC) { 1627 } else if (state == MONOMORPHIC) {
1602 // Only move to megamorphic if the target changes. 1628 // Only move to megamorphic if the target changes.
1603 if (target() != Code::cast(code)) { 1629 if (target() != Code::cast(code)) {
1604 set_target((strict_mode == kStrictMode) 1630 set_target((strict_mode == kStrictMode)
1605 ? megamorphic_stub_strict() 1631 ? megamorphic_stub_strict()
1606 : megamorphic_stub()); 1632 : megamorphic_stub());
1607 } 1633 }
1608 } else if (state == MEGAMORPHIC) { 1634 } else if (state == MEGAMORPHIC) {
1609 // Update the stub cache. 1635 // Update the stub cache.
1610 StubCache::Set(*name, receiver->map(), Code::cast(code)); 1636 isolate()->stub_cache()->Set(*name,
1637 receiver->map(),
1638 Code::cast(code));
1611 } 1639 }
1612 1640
1613 #ifdef DEBUG 1641 #ifdef DEBUG
1614 TraceIC("StoreIC", name, state, target()); 1642 TraceIC("StoreIC", name, state, target());
1615 #endif 1643 #endif
1616 } 1644 }
1617 1645
1618 1646
1619 MaybeObject* KeyedStoreIC::Store(State state, 1647 MaybeObject* KeyedStoreIC::Store(State state,
1620 StrictModeFlag strict_mode, 1648 StrictModeFlag strict_mode,
1621 Handle<Object> object, 1649 Handle<Object> object,
1622 Handle<Object> key, 1650 Handle<Object> key,
1623 Handle<Object> value) { 1651 Handle<Object> value) {
1624 if (key->IsSymbol()) { 1652 if (key->IsSymbol()) {
1625 Handle<String> name = Handle<String>::cast(key); 1653 Handle<String> name = Handle<String>::cast(key);
1626 1654
1627 // If the object is undefined or null it's illegal to try to set any 1655 // If the object is undefined or null it's illegal to try to set any
1628 // properties on it; throw a TypeError in that case. 1656 // properties on it; throw a TypeError in that case.
1629 if (object->IsUndefined() || object->IsNull()) { 1657 if (object->IsUndefined() || object->IsNull()) {
1630 return TypeError("non_object_property_store", object, name); 1658 return TypeError("non_object_property_store", object, name);
1631 } 1659 }
1632 1660
1633 // Ignore stores where the receiver is not a JSObject. 1661 // Ignore stores where the receiver is not a JSObject.
1634 if (!object->IsJSObject()) return *value; 1662 if (!object->IsJSObject()) return *value;
1635 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1663 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1636 1664
1637 // Check if the given name is an array index. 1665 // Check if the given name is an array index.
1638 uint32_t index; 1666 uint32_t index;
1639 if (name->AsArrayIndex(&index)) { 1667 if (name->AsArrayIndex(&index)) {
1640 HandleScope scope; 1668 HandleScope scope(isolate());
1641 Handle<Object> result = SetElement(receiver, index, value, strict_mode); 1669 Handle<Object> result = SetElement(receiver, index, value, strict_mode);
1642 if (result.is_null()) return Failure::Exception(); 1670 if (result.is_null()) return Failure::Exception();
1643 return *value; 1671 return *value;
1644 } 1672 }
1645 1673
1646 // Lookup the property locally in the receiver. 1674 // Lookup the property locally in the receiver.
1647 LookupResult lookup; 1675 LookupResult lookup;
1648 receiver->LocalLookup(*name, &lookup); 1676 receiver->LocalLookup(*name, &lookup);
1649 1677
1650 // Update inline cache and stub cache. 1678 // Update inline cache and stub cache.
(...skipping 11 matching lines...) Expand all
1662 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 1690 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
1663 1691
1664 if (use_ic) { 1692 if (use_ic) {
1665 Code* stub = 1693 Code* stub =
1666 (strict_mode == kStrictMode) ? generic_stub_strict() : generic_stub(); 1694 (strict_mode == kStrictMode) ? generic_stub_strict() : generic_stub();
1667 if (state == UNINITIALIZED) { 1695 if (state == UNINITIALIZED) {
1668 if (object->IsJSObject()) { 1696 if (object->IsJSObject()) {
1669 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1697 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1670 if (receiver->HasExternalArrayElements()) { 1698 if (receiver->HasExternalArrayElements()) {
1671 MaybeObject* probe = 1699 MaybeObject* probe =
1672 StubCache::ComputeKeyedLoadOrStoreExternalArray( 1700 isolate()->stub_cache()->ComputeKeyedLoadOrStoreExternalArray(
1673 *receiver, true, strict_mode); 1701 *receiver, true, strict_mode);
1674 stub = probe->IsFailure() ? 1702 stub = probe->IsFailure() ?
1675 NULL : Code::cast(probe->ToObjectUnchecked()); 1703 NULL : Code::cast(probe->ToObjectUnchecked());
1676 } else if (key->IsSmi() && receiver->map()->has_fast_elements()) { 1704 } else if (key->IsSmi() && receiver->map()->has_fast_elements()) {
1677 MaybeObject* probe = 1705 MaybeObject* probe =
1678 StubCache::ComputeKeyedStoreSpecialized(*receiver, strict_mode); 1706 isolate()->stub_cache()->ComputeKeyedStoreSpecialized(
1707 *receiver, strict_mode);
1679 stub = probe->IsFailure() ? 1708 stub = probe->IsFailure() ?
1680 NULL : Code::cast(probe->ToObjectUnchecked()); 1709 NULL : Code::cast(probe->ToObjectUnchecked());
1681 } 1710 }
1682 } 1711 }
1683 } 1712 }
1684 if (stub != NULL) set_target(stub); 1713 if (stub != NULL) set_target(stub);
1685 } 1714 }
1686 1715
1687 // Set the property. 1716 // Set the property.
1688 return Runtime::SetObjectProperty(object, key, value, NONE, strict_mode); 1717 return Runtime::SetObjectProperty(
1718 isolate(), object , key, value, NONE, strict_mode);
1689 } 1719 }
1690 1720
1691 1721
1692 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, 1722 void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
1693 State state, 1723 State state,
1694 StrictModeFlag strict_mode, 1724 StrictModeFlag strict_mode,
1695 Handle<JSObject> receiver, 1725 Handle<JSObject> receiver,
1696 Handle<String> name, 1726 Handle<String> name,
1697 Handle<Object> value) { 1727 Handle<Object> value) {
1698 // Skip JSGlobalProxy. 1728 // Skip JSGlobalProxy.
(...skipping 12 matching lines...) Expand all
1711 PropertyType type = lookup->type(); 1741 PropertyType type = lookup->type();
1712 1742
1713 // Compute the code stub for this store; used for rewriting to 1743 // Compute the code stub for this store; used for rewriting to
1714 // monomorphic state and making sure that the code stub is in the 1744 // monomorphic state and making sure that the code stub is in the
1715 // stub cache. 1745 // stub cache.
1716 MaybeObject* maybe_code = NULL; 1746 MaybeObject* maybe_code = NULL;
1717 Object* code = NULL; 1747 Object* code = NULL;
1718 1748
1719 switch (type) { 1749 switch (type) {
1720 case FIELD: { 1750 case FIELD: {
1721 maybe_code = StubCache::ComputeKeyedStoreField( 1751 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField(
1722 *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode); 1752 *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode);
1723 break; 1753 break;
1724 } 1754 }
1725 case MAP_TRANSITION: { 1755 case MAP_TRANSITION: {
1726 if (lookup->GetAttributes() == NONE) { 1756 if (lookup->GetAttributes() == NONE) {
1727 HandleScope scope; 1757 HandleScope scope(isolate());
1728 ASSERT(type == MAP_TRANSITION); 1758 ASSERT(type == MAP_TRANSITION);
1729 Handle<Map> transition(lookup->GetTransitionMap()); 1759 Handle<Map> transition(lookup->GetTransitionMap());
1730 int index = transition->PropertyIndexFor(*name); 1760 int index = transition->PropertyIndexFor(*name);
1731 maybe_code = StubCache::ComputeKeyedStoreField( 1761 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField(
1732 *name, *receiver, index, *transition, strict_mode); 1762 *name, *receiver, index, *transition, strict_mode);
1733 break; 1763 break;
1734 } 1764 }
1735 // fall through. 1765 // fall through.
1736 } 1766 }
1737 default: { 1767 default: {
1738 // Always rewrite to the generic case so that we do not 1768 // Always rewrite to the generic case so that we do not
1739 // repeatedly try to rewrite. 1769 // repeatedly try to rewrite.
1740 maybe_code = (strict_mode == kStrictMode) 1770 maybe_code = (strict_mode == kStrictMode)
1741 ? generic_stub_strict() 1771 ? generic_stub_strict()
(...skipping 20 matching lines...) Expand all
1762 #ifdef DEBUG 1792 #ifdef DEBUG
1763 TraceIC("KeyedStoreIC", name, state, target()); 1793 TraceIC("KeyedStoreIC", name, state, target());
1764 #endif 1794 #endif
1765 } 1795 }
1766 1796
1767 1797
1768 // ---------------------------------------------------------------------------- 1798 // ----------------------------------------------------------------------------
1769 // Static IC stub generators. 1799 // Static IC stub generators.
1770 // 1800 //
1771 1801
1772 static JSFunction* CompileFunction(JSFunction* function, 1802 static JSFunction* CompileFunction(Isolate* isolate,
1803 JSFunction* function,
1773 InLoopFlag in_loop) { 1804 InLoopFlag in_loop) {
1774 // Compile now with optimization. 1805 // Compile now with optimization.
1775 HandleScope scope; 1806 HandleScope scope(isolate);
1776 Handle<JSFunction> function_handle(function); 1807 Handle<JSFunction> function_handle(function, isolate);
1777 if (in_loop == IN_LOOP) { 1808 if (in_loop == IN_LOOP) {
1778 CompileLazyInLoop(function_handle, CLEAR_EXCEPTION); 1809 CompileLazyInLoop(function_handle, CLEAR_EXCEPTION);
1779 } else { 1810 } else {
1780 CompileLazy(function_handle, CLEAR_EXCEPTION); 1811 CompileLazy(function_handle, CLEAR_EXCEPTION);
1781 } 1812 }
1782 return *function_handle; 1813 return *function_handle;
1783 } 1814 }
1784 1815
1785 1816
1786 // Used from ic-<arch>.cc. 1817 // Used from ic-<arch>.cc.
1787 MUST_USE_RESULT MaybeObject* CallIC_Miss(Arguments args) { 1818 MUST_USE_RESULT MaybeObject* CallIC_Miss(RUNTIME_CALLING_CONVENTION) {
1819 RUNTIME_GET_ISOLATE;
1788 NoHandleAllocation na; 1820 NoHandleAllocation na;
1789 ASSERT(args.length() == 2); 1821 ASSERT(args.length() == 2);
1790 CallIC ic; 1822 CallIC ic(isolate);
1791 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1823 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1792 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 1824 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1793 MaybeObject* maybe_result = ic.LoadFunction(state, 1825 MaybeObject* maybe_result = ic.LoadFunction(state,
1794 extra_ic_state, 1826 extra_ic_state,
1795 args.at<Object>(0), 1827 args.at<Object>(0),
1796 args.at<String>(1)); 1828 args.at<String>(1));
1797 Object* result; 1829 Object* result;
1798 if (!maybe_result->ToObject(&result)) return maybe_result; 1830 if (!maybe_result->ToObject(&result)) return maybe_result;
1799 1831
1800 // The first time the inline cache is updated may be the first time the 1832 // The first time the inline cache is updated may be the first time the
1801 // function it references gets called. If the function was lazily compiled 1833 // function it references gets called. If the function was lazily compiled
1802 // then the first call will trigger a compilation. We check for this case 1834 // then the first call will trigger a compilation. We check for this case
1803 // and we do the compilation immediately, instead of waiting for the stub 1835 // and we do the compilation immediately, instead of waiting for the stub
1804 // currently attached to the JSFunction object to trigger compilation. We 1836 // currently attached to the JSFunction object to trigger compilation. We
1805 // do this in the case where we know that the inline cache is inside a loop, 1837 // do this in the case where we know that the inline cache is inside a loop,
1806 // because then we know that we want to optimize the function. 1838 // because then we know that we want to optimize the function.
1807 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { 1839 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
1808 return result; 1840 return result;
1809 } 1841 }
1810 return CompileFunction(JSFunction::cast(result), ic.target()->ic_in_loop()); 1842 return CompileFunction(isolate,
1843 JSFunction::cast(result),
1844 ic.target()->ic_in_loop());
1811 } 1845 }
1812 1846
1813 1847
1814 // Used from ic-<arch>.cc. 1848 // Used from ic-<arch>.cc.
1815 MUST_USE_RESULT MaybeObject* KeyedCallIC_Miss(Arguments args) { 1849 MUST_USE_RESULT MaybeObject* KeyedCallIC_Miss(RUNTIME_CALLING_CONVENTION) {
1850 RUNTIME_GET_ISOLATE;
1816 NoHandleAllocation na; 1851 NoHandleAllocation na;
1817 ASSERT(args.length() == 2); 1852 ASSERT(args.length() == 2);
1818 KeyedCallIC ic; 1853 KeyedCallIC ic(isolate);
1819 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1854 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1820 Object* result; 1855 Object* result;
1821 { MaybeObject* maybe_result = 1856 { MaybeObject* maybe_result =
1822 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); 1857 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1));
1823 if (!maybe_result->ToObject(&result)) return maybe_result; 1858 if (!maybe_result->ToObject(&result)) return maybe_result;
1824 } 1859 }
1825 1860
1826 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { 1861 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
1827 return result; 1862 return result;
1828 } 1863 }
1829 return CompileFunction(JSFunction::cast(result), ic.target()->ic_in_loop()); 1864 return CompileFunction(isolate,
1865 JSFunction::cast(result),
1866 ic.target()->ic_in_loop());
1830 } 1867 }
1831 1868
1832 1869
1833 // Used from ic-<arch>.cc. 1870 // Used from ic-<arch>.cc.
1834 MUST_USE_RESULT MaybeObject* LoadIC_Miss(Arguments args) { 1871 MUST_USE_RESULT MaybeObject* LoadIC_Miss(RUNTIME_CALLING_CONVENTION) {
1872 RUNTIME_GET_ISOLATE;
1835 NoHandleAllocation na; 1873 NoHandleAllocation na;
1836 ASSERT(args.length() == 2); 1874 ASSERT(args.length() == 2);
1837 LoadIC ic; 1875 LoadIC ic(isolate);
1838 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1876 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1839 return ic.Load(state, args.at<Object>(0), args.at<String>(1)); 1877 return ic.Load(state, args.at<Object>(0), args.at<String>(1));
1840 } 1878 }
1841 1879
1842 1880
1843 // Used from ic-<arch>.cc 1881 // Used from ic-<arch>.cc
1844 MUST_USE_RESULT MaybeObject* KeyedLoadIC_Miss(Arguments args) { 1882 MUST_USE_RESULT MaybeObject* KeyedLoadIC_Miss(RUNTIME_CALLING_CONVENTION) {
1883 RUNTIME_GET_ISOLATE;
1845 NoHandleAllocation na; 1884 NoHandleAllocation na;
1846 ASSERT(args.length() == 2); 1885 ASSERT(args.length() == 2);
1847 KeyedLoadIC ic; 1886 KeyedLoadIC ic(isolate);
1848 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1887 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1849 return ic.Load(state, args.at<Object>(0), args.at<Object>(1)); 1888 return ic.Load(state, args.at<Object>(0), args.at<Object>(1));
1850 } 1889 }
1851 1890
1852 1891
1853 // Used from ic-<arch>.cc. 1892 // Used from ic-<arch>.cc.
1854 MUST_USE_RESULT MaybeObject* StoreIC_Miss(Arguments args) { 1893 MUST_USE_RESULT MaybeObject* StoreIC_Miss(RUNTIME_CALLING_CONVENTION) {
1894 RUNTIME_GET_ISOLATE;
1855 NoHandleAllocation na; 1895 NoHandleAllocation na;
1856 ASSERT(args.length() == 3); 1896 ASSERT(args.length() == 3);
1857 StoreIC ic; 1897 StoreIC ic(isolate);
1858 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1898 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1859 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 1899 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1860 return ic.Store(state, 1900 return ic.Store(state,
1861 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), 1901 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode),
1862 args.at<Object>(0), 1902 args.at<Object>(0),
1863 args.at<String>(1), 1903 args.at<String>(1),
1864 args.at<Object>(2)); 1904 args.at<Object>(2));
1865 } 1905 }
1866 1906
1867 1907
1868 MUST_USE_RESULT MaybeObject* StoreIC_ArrayLength(Arguments args) { 1908 MUST_USE_RESULT MaybeObject* StoreIC_ArrayLength(RUNTIME_CALLING_CONVENTION) {
1909 RUNTIME_GET_ISOLATE;
1869 NoHandleAllocation nha; 1910 NoHandleAllocation nha;
1870 1911
1871 ASSERT(args.length() == 2); 1912 ASSERT(args.length() == 2);
1872 JSObject* receiver = JSObject::cast(args[0]); 1913 JSObject* receiver = JSObject::cast(args[0]);
1873 Object* len = args[1]; 1914 Object* len = args[1];
1874 1915
1875 // The generated code should filter out non-Smis before we get here. 1916 // The generated code should filter out non-Smis before we get here.
1876 ASSERT(len->IsSmi()); 1917 ASSERT(len->IsSmi());
1877 1918
1878 Object* result; 1919 Object* result;
1879 { MaybeObject* maybe_result = receiver->SetElementsLength(len); 1920 { MaybeObject* maybe_result = receiver->SetElementsLength(len);
1880 if (!maybe_result->ToObject(&result)) return maybe_result; 1921 if (!maybe_result->ToObject(&result)) return maybe_result;
1881 } 1922 }
1882 return len; 1923 return len;
1883 } 1924 }
1884 1925
1885 1926
1886 // Extend storage is called in a store inline cache when 1927 // Extend storage is called in a store inline cache when
1887 // it is necessary to extend the properties array of a 1928 // it is necessary to extend the properties array of a
1888 // JSObject. 1929 // JSObject.
1889 MUST_USE_RESULT MaybeObject* SharedStoreIC_ExtendStorage(Arguments args) { 1930 MUST_USE_RESULT MaybeObject* SharedStoreIC_ExtendStorage(
1931 RUNTIME_CALLING_CONVENTION) {
1932 RUNTIME_GET_ISOLATE;
1890 NoHandleAllocation na; 1933 NoHandleAllocation na;
1891 ASSERT(args.length() == 3); 1934 ASSERT(args.length() == 3);
1892 1935
1893 // Convert the parameters 1936 // Convert the parameters
1894 JSObject* object = JSObject::cast(args[0]); 1937 JSObject* object = JSObject::cast(args[0]);
1895 Map* transition = Map::cast(args[1]); 1938 Map* transition = Map::cast(args[1]);
1896 Object* value = args[2]; 1939 Object* value = args[2];
1897 1940
1898 // Check the object has run out out property space. 1941 // Check the object has run out out property space.
1899 ASSERT(object->HasFastProperties()); 1942 ASSERT(object->HasFastProperties());
(...skipping 13 matching lines...) Expand all
1913 // Set the new property value and do the map transition. 1956 // Set the new property value and do the map transition.
1914 object->set_properties(new_storage); 1957 object->set_properties(new_storage);
1915 object->set_map(transition); 1958 object->set_map(transition);
1916 1959
1917 // Return the stored value. 1960 // Return the stored value.
1918 return value; 1961 return value;
1919 } 1962 }
1920 1963
1921 1964
1922 // Used from ic-<arch>.cc. 1965 // Used from ic-<arch>.cc.
1923 MUST_USE_RESULT MaybeObject* KeyedStoreIC_Miss(Arguments args) { 1966 MUST_USE_RESULT MaybeObject* KeyedStoreIC_Miss(RUNTIME_CALLING_CONVENTION) {
1967 RUNTIME_GET_ISOLATE;
1924 NoHandleAllocation na; 1968 NoHandleAllocation na;
1925 ASSERT(args.length() == 3); 1969 ASSERT(args.length() == 3);
1926 KeyedStoreIC ic; 1970 KeyedStoreIC ic(isolate);
1927 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1971 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1928 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 1972 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1929 return ic.Store(state, 1973 return ic.Store(state,
1930 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), 1974 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode),
1931 args.at<Object>(0), 1975 args.at<Object>(0),
1932 args.at<Object>(1), 1976 args.at<Object>(1),
1933 args.at<Object>(2)); 1977 args.at<Object>(2));
1934 } 1978 }
1935 1979
1936 1980
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1986 } 2030 }
1987 2031
1988 return GENERIC; 2032 return GENERIC;
1989 } 2033 }
1990 2034
1991 2035
1992 // defined in code-stubs-<arch>.cc 2036 // defined in code-stubs-<arch>.cc
1993 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info); 2037 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info);
1994 2038
1995 2039
1996 MUST_USE_RESULT MaybeObject* BinaryOp_Patch(Arguments args) { 2040 MUST_USE_RESULT MaybeObject* BinaryOp_Patch(RUNTIME_CALLING_CONVENTION) {
2041 RUNTIME_GET_ISOLATE;
1997 ASSERT(args.length() == 5); 2042 ASSERT(args.length() == 5);
1998 2043
1999 HandleScope scope; 2044 HandleScope scope(isolate);
2000 Handle<Object> left = args.at<Object>(0); 2045 Handle<Object> left = args.at<Object>(0);
2001 Handle<Object> right = args.at<Object>(1); 2046 Handle<Object> right = args.at<Object>(1);
2002 int key = Smi::cast(args[2])->value(); 2047 int key = Smi::cast(args[2])->value();
2003 Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value()); 2048 Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value());
2004 BinaryOpIC::TypeInfo previous_type = 2049 BinaryOpIC::TypeInfo previous_type =
2005 static_cast<BinaryOpIC::TypeInfo>(Smi::cast(args[4])->value()); 2050 static_cast<BinaryOpIC::TypeInfo>(Smi::cast(args[4])->value());
2006 2051
2007 BinaryOpIC::TypeInfo type = BinaryOpIC::GetTypeInfo(*left, *right); 2052 BinaryOpIC::TypeInfo type = BinaryOpIC::GetTypeInfo(*left, *right);
2008 Handle<Code> code = GetBinaryOpStub(key, type); 2053 Handle<Code> code = GetBinaryOpStub(key, type);
2009 if (!code.is_null()) { 2054 if (!code.is_null()) {
2010 BinaryOpIC ic; 2055 BinaryOpIC ic(isolate);
2011 ic.patch(*code); 2056 ic.patch(*code);
2012 if (FLAG_trace_ic) { 2057 if (FLAG_trace_ic) {
2013 PrintF("[BinaryOpIC (%s->%s)#%s]\n", 2058 PrintF("[BinaryOpIC (%s->%s)#%s]\n",
2014 BinaryOpIC::GetName(previous_type), 2059 BinaryOpIC::GetName(previous_type),
2015 BinaryOpIC::GetName(type), 2060 BinaryOpIC::GetName(type),
2016 Token::Name(op)); 2061 Token::Name(op));
2017 } 2062 }
2018 } 2063 }
2019 2064
2020 Handle<JSBuiltinsObject> builtins = Top::builtins(); 2065 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>(
2066 isolate->thread_local_top()->context_->builtins(), isolate);
2021 Object* builtin = NULL; // Initialization calms down the compiler. 2067 Object* builtin = NULL; // Initialization calms down the compiler.
2022 switch (op) { 2068 switch (op) {
2023 case Token::ADD: 2069 case Token::ADD:
2024 builtin = builtins->javascript_builtin(Builtins::ADD); 2070 builtin = builtins->javascript_builtin(Builtins::ADD);
2025 break; 2071 break;
2026 case Token::SUB: 2072 case Token::SUB:
2027 builtin = builtins->javascript_builtin(Builtins::SUB); 2073 builtin = builtins->javascript_builtin(Builtins::SUB);
2028 break; 2074 break;
2029 case Token::MUL: 2075 case Token::MUL:
2030 builtin = builtins->javascript_builtin(Builtins::MUL); 2076 builtin = builtins->javascript_builtin(Builtins::MUL);
(...skipping 19 matching lines...) Expand all
2050 case Token::SAR: 2096 case Token::SAR:
2051 builtin = builtins->javascript_builtin(Builtins::SAR); 2097 builtin = builtins->javascript_builtin(Builtins::SAR);
2052 break; 2098 break;
2053 case Token::SHL: 2099 case Token::SHL:
2054 builtin = builtins->javascript_builtin(Builtins::SHL); 2100 builtin = builtins->javascript_builtin(Builtins::SHL);
2055 break; 2101 break;
2056 default: 2102 default:
2057 UNREACHABLE(); 2103 UNREACHABLE();
2058 } 2104 }
2059 2105
2060 Handle<JSFunction> builtin_function(JSFunction::cast(builtin)); 2106 Handle<JSFunction> builtin_function(JSFunction::cast(builtin),
2107 isolate);
2061 2108
2062 bool caught_exception; 2109 bool caught_exception;
2063 Object** builtin_args[] = { right.location() }; 2110 Object** builtin_args[] = { right.location() };
2064 Handle<Object> result = Execution::Call(builtin_function, 2111 Handle<Object> result = Execution::Call(builtin_function,
2065 left, 2112 left,
2066 ARRAY_SIZE(builtin_args), 2113 ARRAY_SIZE(builtin_args),
2067 builtin_args, 2114 builtin_args,
2068 &caught_exception); 2115 &caught_exception);
2069 if (caught_exception) { 2116 if (caught_exception) {
2070 return Failure::Exception(); 2117 return Failure::Exception();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2149 } 2196 }
2150 2197
2151 2198
2152 // defined in code-stubs-<arch>.cc 2199 // defined in code-stubs-<arch>.cc
2153 // Only needed to remove dependency of ic.cc on code-stubs-<arch>.h. 2200 // Only needed to remove dependency of ic.cc on code-stubs-<arch>.h.
2154 Handle<Code> GetTypeRecordingBinaryOpStub(int key, 2201 Handle<Code> GetTypeRecordingBinaryOpStub(int key,
2155 TRBinaryOpIC::TypeInfo type_info, 2202 TRBinaryOpIC::TypeInfo type_info,
2156 TRBinaryOpIC::TypeInfo result_type); 2203 TRBinaryOpIC::TypeInfo result_type);
2157 2204
2158 2205
2159 MaybeObject* TypeRecordingBinaryOp_Patch(Arguments args) { 2206 MaybeObject* TypeRecordingBinaryOp_Patch(RUNTIME_CALLING_CONVENTION) {
2207 RUNTIME_GET_ISOLATE;
2160 ASSERT(args.length() == 5); 2208 ASSERT(args.length() == 5);
2161 2209
2162 HandleScope scope; 2210 HandleScope scope(isolate);
2163 Handle<Object> left = args.at<Object>(0); 2211 Handle<Object> left = args.at<Object>(0);
2164 Handle<Object> right = args.at<Object>(1); 2212 Handle<Object> right = args.at<Object>(1);
2165 int key = Smi::cast(args[2])->value(); 2213 int key = Smi::cast(args[2])->value();
2166 Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value()); 2214 Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value());
2167 TRBinaryOpIC::TypeInfo previous_type = 2215 TRBinaryOpIC::TypeInfo previous_type =
2168 static_cast<TRBinaryOpIC::TypeInfo>(Smi::cast(args[4])->value()); 2216 static_cast<TRBinaryOpIC::TypeInfo>(Smi::cast(args[4])->value());
2169 2217
2170 TRBinaryOpIC::TypeInfo type = TRBinaryOpIC::GetTypeInfo(left, right); 2218 TRBinaryOpIC::TypeInfo type = TRBinaryOpIC::GetTypeInfo(left, right);
2171 type = TRBinaryOpIC::JoinTypes(type, previous_type); 2219 type = TRBinaryOpIC::JoinTypes(type, previous_type);
2172 TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED; 2220 TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED;
(...skipping 21 matching lines...) Expand all
2194 2242
2195 Handle<Code> code = GetTypeRecordingBinaryOpStub(key, type, result_type); 2243 Handle<Code> code = GetTypeRecordingBinaryOpStub(key, type, result_type);
2196 if (!code.is_null()) { 2244 if (!code.is_null()) {
2197 if (FLAG_trace_ic) { 2245 if (FLAG_trace_ic) {
2198 PrintF("[TypeRecordingBinaryOpIC (%s->(%s->%s))#%s]\n", 2246 PrintF("[TypeRecordingBinaryOpIC (%s->(%s->%s))#%s]\n",
2199 TRBinaryOpIC::GetName(previous_type), 2247 TRBinaryOpIC::GetName(previous_type),
2200 TRBinaryOpIC::GetName(type), 2248 TRBinaryOpIC::GetName(type),
2201 TRBinaryOpIC::GetName(result_type), 2249 TRBinaryOpIC::GetName(result_type),
2202 Token::Name(op)); 2250 Token::Name(op));
2203 } 2251 }
2204 TRBinaryOpIC ic; 2252 TRBinaryOpIC ic(isolate);
2205 ic.patch(*code); 2253 ic.patch(*code);
2206 2254
2207 // Activate inlined smi code. 2255 // Activate inlined smi code.
2208 if (previous_type == TRBinaryOpIC::UNINITIALIZED) { 2256 if (previous_type == TRBinaryOpIC::UNINITIALIZED) {
2209 PatchInlinedSmiCode(ic.address()); 2257 PatchInlinedSmiCode(ic.address());
2210 } 2258 }
2211 } 2259 }
2212 2260
2213 Handle<JSBuiltinsObject> builtins = Top::builtins(); 2261 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>(
2262 isolate->thread_local_top()->context_->builtins(), isolate);
2214 Object* builtin = NULL; // Initialization calms down the compiler. 2263 Object* builtin = NULL; // Initialization calms down the compiler.
2215 switch (op) { 2264 switch (op) {
2216 case Token::ADD: 2265 case Token::ADD:
2217 builtin = builtins->javascript_builtin(Builtins::ADD); 2266 builtin = builtins->javascript_builtin(Builtins::ADD);
2218 break; 2267 break;
2219 case Token::SUB: 2268 case Token::SUB:
2220 builtin = builtins->javascript_builtin(Builtins::SUB); 2269 builtin = builtins->javascript_builtin(Builtins::SUB);
2221 break; 2270 break;
2222 case Token::MUL: 2271 case Token::MUL:
2223 builtin = builtins->javascript_builtin(Builtins::MUL); 2272 builtin = builtins->javascript_builtin(Builtins::MUL);
(...skipping 19 matching lines...) Expand all
2243 case Token::SAR: 2292 case Token::SAR:
2244 builtin = builtins->javascript_builtin(Builtins::SAR); 2293 builtin = builtins->javascript_builtin(Builtins::SAR);
2245 break; 2294 break;
2246 case Token::SHL: 2295 case Token::SHL:
2247 builtin = builtins->javascript_builtin(Builtins::SHL); 2296 builtin = builtins->javascript_builtin(Builtins::SHL);
2248 break; 2297 break;
2249 default: 2298 default:
2250 UNREACHABLE(); 2299 UNREACHABLE();
2251 } 2300 }
2252 2301
2253 Handle<JSFunction> builtin_function(JSFunction::cast(builtin)); 2302 Handle<JSFunction> builtin_function(JSFunction::cast(builtin), isolate);
2254 2303
2255 bool caught_exception; 2304 bool caught_exception;
2256 Object** builtin_args[] = { right.location() }; 2305 Object** builtin_args[] = { right.location() };
2257 Handle<Object> result = Execution::Call(builtin_function, 2306 Handle<Object> result = Execution::Call(builtin_function,
2258 left, 2307 left,
2259 ARRAY_SIZE(builtin_args), 2308 ARRAY_SIZE(builtin_args),
2260 builtin_args, 2309 builtin_args,
2261 &caught_exception); 2310 &caught_exception);
2262 if (caught_exception) { 2311 if (caught_exception) {
2263 return Failure::Exception(); 2312 return Failure::Exception();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2303 if ((state == UNINITIALIZED || (state == SMIS && has_inlined_smi_code)) && 2352 if ((state == UNINITIALIZED || (state == SMIS && has_inlined_smi_code)) &&
2304 x->IsNumber() && y->IsNumber()) return HEAP_NUMBERS; 2353 x->IsNumber() && y->IsNumber()) return HEAP_NUMBERS;
2305 if (op_ != Token::EQ && op_ != Token::EQ_STRICT) return GENERIC; 2354 if (op_ != Token::EQ && op_ != Token::EQ_STRICT) return GENERIC;
2306 if (state == UNINITIALIZED && 2355 if (state == UNINITIALIZED &&
2307 x->IsJSObject() && y->IsJSObject()) return OBJECTS; 2356 x->IsJSObject() && y->IsJSObject()) return OBJECTS;
2308 return GENERIC; 2357 return GENERIC;
2309 } 2358 }
2310 2359
2311 2360
2312 // Used from ic_<arch>.cc. 2361 // Used from ic_<arch>.cc.
2313 Code* CompareIC_Miss(Arguments args) { 2362 Code* CompareIC_Miss(RUNTIME_CALLING_CONVENTION) {
2363 RUNTIME_GET_ISOLATE;
2314 NoHandleAllocation na; 2364 NoHandleAllocation na;
2315 ASSERT(args.length() == 3); 2365 ASSERT(args.length() == 3);
2316 CompareIC ic(static_cast<Token::Value>(Smi::cast(args[2])->value())); 2366 CompareIC ic(isolate, static_cast<Token::Value>(Smi::cast(args[2])->value()));
2317 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); 2367 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1));
2318 return ic.target(); 2368 return ic.target();
2319 } 2369 }
2320 2370
2321 2371
2322 static Address IC_utilities[] = { 2372 static const Address IC_utilities[] = {
2323 #define ADDR(name) FUNCTION_ADDR(name), 2373 #define ADDR(name) FUNCTION_ADDR(name),
2324 IC_UTIL_LIST(ADDR) 2374 IC_UTIL_LIST(ADDR)
2325 NULL 2375 NULL
2326 #undef ADDR 2376 #undef ADDR
2327 }; 2377 };
2328 2378
2329 2379
2330 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2380 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2331 return IC_utilities[id]; 2381 return IC_utilities[id];
2332 } 2382 }
2333 2383
2334 2384
2335 } } // namespace v8::internal 2385 } } // 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