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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 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/x64/macro-assembler-x64.cc ('k') | src/x64/virtual-frame-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 __ movq(dst, FieldOperand(src, offset)); 126 __ movq(dst, FieldOperand(src, offset));
127 } else { 127 } else {
128 // Calculate the offset into the properties array. 128 // Calculate the offset into the properties array.
129 int offset = index * kPointerSize + FixedArray::kHeaderSize; 129 int offset = index * kPointerSize + FixedArray::kHeaderSize;
130 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 130 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset));
131 __ movq(dst, FieldOperand(dst, offset)); 131 __ movq(dst, FieldOperand(dst, offset));
132 } 132 }
133 } 133 }
134 134
135 135
136 template <typename Pushable>
137 static void PushInterceptorArguments(MacroAssembler* masm, 136 static void PushInterceptorArguments(MacroAssembler* masm,
138 Register receiver, 137 Register receiver,
139 Register holder, 138 Register holder,
140 Pushable name, 139 Register name,
141 JSObject* holder_obj) { 140 JSObject* holder_obj) {
142 __ push(receiver); 141 __ push(receiver);
143 __ push(holder); 142 __ push(holder);
144 __ push(name); 143 __ push(name);
145 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); 144 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
146 ASSERT(!Heap::InNewSpace(interceptor)); 145 ASSERT(!Heap::InNewSpace(interceptor));
147 __ movq(kScratchRegister, Handle<Object>(interceptor), 146 __ movq(kScratchRegister, Handle<Object>(interceptor),
148 RelocInfo::EMBEDDED_OBJECT); 147 RelocInfo::EMBEDDED_OBJECT);
149 __ push(kScratchRegister); 148 __ push(kScratchRegister);
150 __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset)); 149 __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 193
195 // Probe the secondary table. 194 // Probe the secondary table.
196 ProbeTable(masm, flags, kSecondary, name, scratch); 195 ProbeTable(masm, flags, kSecondary, name, scratch);
197 196
198 // Cache miss: Fall-through and let caller handle the miss by 197 // Cache miss: Fall-through and let caller handle the miss by
199 // entering the runtime system. 198 // entering the runtime system.
200 __ bind(&miss); 199 __ bind(&miss);
201 } 200 }
202 201
203 202
203 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
204 // but may be destroyed if store is successful.
204 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 205 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
205 Builtins::Name storage_extend,
206 JSObject* object, 206 JSObject* object,
207 int index, 207 int index,
208 Map* transition, 208 Map* transition,
209 Register receiver_reg, 209 Register receiver_reg,
210 Register name_reg, 210 Register name_reg,
211 Register scratch, 211 Register scratch,
212 Label* miss_label) { 212 Label* miss_label) {
213 // Check that the object isn't a smi. 213 // Check that the object isn't a smi.
214 __ JumpIfSmi(receiver_reg, miss_label); 214 __ JumpIfSmi(receiver_reg, miss_label);
215 215
216 // Check that the map of the object hasn't changed. 216 // Check that the map of the object hasn't changed.
217 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), 217 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
218 Handle<Map>(object->map())); 218 Handle<Map>(object->map()));
219 __ j(not_equal, miss_label); 219 __ j(not_equal, miss_label);
220 220
221 // Perform global security token check if needed. 221 // Perform global security token check if needed.
222 if (object->IsJSGlobalProxy()) { 222 if (object->IsJSGlobalProxy()) {
223 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); 223 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
224 } 224 }
225 225
226 // Stub never generated for non-global objects that require access 226 // Stub never generated for non-global objects that require access
227 // checks. 227 // checks.
228 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 228 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
229 229
230 // Perform map transition for the receiver if necessary. 230 // Perform map transition for the receiver if necessary.
231 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { 231 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) {
232 // The properties must be extended before we can store the value. 232 // The properties must be extended before we can store the value.
233 // We jump to a runtime call that extends the properties array. 233 // We jump to a runtime call that extends the properties array.
234 __ Move(rcx, Handle<Map>(transition)); 234 __ pop(scratch); // Return address.
235 Handle<Code> ic(Builtins::builtin(storage_extend)); 235 __ push(receiver_reg);
236 __ Jump(ic, RelocInfo::CODE_TARGET); 236 __ Push(Handle<Map>(transition));
237 __ push(rax);
238 __ push(scratch);
239 __ TailCallRuntime(
240 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1);
237 return; 241 return;
238 } 242 }
239 243
240 if (transition != NULL) { 244 if (transition != NULL) {
241 // Update the map of the object; no write barrier updating is 245 // Update the map of the object; no write barrier updating is
242 // needed because the map is never in new space. 246 // needed because the map is never in new space.
243 __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset), 247 __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset),
244 Handle<Map>(transition)); 248 Handle<Map>(transition));
245 } 249 }
246 250
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 __ movq(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 311 __ movq(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
308 __ movzxbq(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 312 __ movzxbq(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
309 ASSERT(kNotStringTag != 0); 313 ASSERT(kNotStringTag != 0);
310 __ testl(scratch, Immediate(kNotStringTag)); 314 __ testl(scratch, Immediate(kNotStringTag));
311 __ j(not_zero, non_string_object); 315 __ j(not_zero, non_string_object);
312 } 316 }
313 317
314 318
315 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, 319 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
316 Register receiver, 320 Register receiver,
317 Register scratch, 321 Register scratch1,
322 Register scratch2,
318 Label* miss) { 323 Label* miss) {
319 Label load_length, check_wrapper; 324 Label check_wrapper;
320 325
321 // Check if the object is a string leaving the instance type in the 326 // Check if the object is a string leaving the instance type in the
322 // scratch register. 327 // scratch register.
323 GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper); 328 GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
324 329
325 // Load length directly from the string. 330 // Load length directly from the string.
326 __ bind(&load_length);
327 __ movl(rax, FieldOperand(receiver, String::kLengthOffset)); 331 __ movl(rax, FieldOperand(receiver, String::kLengthOffset));
328 __ Integer32ToSmi(rax, rax); 332 __ Integer32ToSmi(rax, rax);
329 __ ret(0); 333 __ ret(0);
330 334
331 // Check if the object is a JSValue wrapper. 335 // Check if the object is a JSValue wrapper.
332 __ bind(&check_wrapper); 336 __ bind(&check_wrapper);
333 __ cmpl(scratch, Immediate(JS_VALUE_TYPE)); 337 __ cmpl(scratch1, Immediate(JS_VALUE_TYPE));
334 __ j(not_equal, miss); 338 __ j(not_equal, miss);
335 339
336 // Check if the wrapped value is a string and load the length 340 // Check if the wrapped value is a string and load the length
337 // directly if it is. 341 // directly if it is.
338 __ movq(receiver, FieldOperand(receiver, JSValue::kValueOffset)); 342 __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
339 GenerateStringCheck(masm, receiver, scratch, miss, miss); 343 GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
340 __ jmp(&load_length); 344 __ movl(rax, FieldOperand(scratch2, String::kLengthOffset));
345 __ Integer32ToSmi(rax, rax);
346 __ ret(0);
341 } 347 }
342 348
343 349
344 template <class Pushable>
345 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, 350 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
346 Register receiver, 351 Register receiver,
347 Register holder, 352 Register holder,
348 Pushable name, 353 Register name,
349 JSObject* holder_obj) { 354 JSObject* holder_obj) {
350 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 355 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
351 356
352 ExternalReference ref = 357 ExternalReference ref =
353 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)); 358 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly));
354 __ movq(rax, Immediate(5)); 359 __ movq(rax, Immediate(5));
355 __ movq(rbx, ref); 360 __ movq(rbx, ref);
356 361
357 CEntryStub stub(1); 362 CEntryStub stub(1);
358 __ CallStub(&stub); 363 __ CallStub(&stub);
(...skipping 28 matching lines...) Expand all
387 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 392 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
388 393
389 // Check that the receiver isn't a smi. 394 // Check that the receiver isn't a smi.
390 __ JumpIfSmi(receiver, miss); 395 __ JumpIfSmi(receiver, miss);
391 396
392 // Check that the maps haven't changed. 397 // Check that the maps haven't changed.
393 Register reg = 398 Register reg =
394 stub_compiler->CheckPrototypes(object, receiver, holder, 399 stub_compiler->CheckPrototypes(object, receiver, holder,
395 scratch1, scratch2, name, miss); 400 scratch1, scratch2, name, miss);
396 401
397 if (lookup->IsValid() && lookup->IsCacheable()) { 402 if (lookup->IsProperty() && lookup->IsCacheable()) {
398 compiler->CompileCacheable(masm, 403 compiler->CompileCacheable(masm,
399 stub_compiler, 404 stub_compiler,
400 receiver, 405 receiver,
401 reg, 406 reg,
402 scratch1, 407 scratch1,
403 scratch2, 408 scratch2,
404 holder, 409 holder,
405 lookup, 410 lookup,
406 name, 411 name,
407 miss); 412 miss);
(...skipping 15 matching lines...) Expand all
423 void CompileCacheable(MacroAssembler* masm, 428 void CompileCacheable(MacroAssembler* masm,
424 StubCompiler* stub_compiler, 429 StubCompiler* stub_compiler,
425 Register receiver, 430 Register receiver,
426 Register holder, 431 Register holder,
427 Register scratch1, 432 Register scratch1,
428 Register scratch2, 433 Register scratch2,
429 JSObject* holder_obj, 434 JSObject* holder_obj,
430 LookupResult* lookup, 435 LookupResult* lookup,
431 String* name, 436 String* name,
432 Label* miss_label) { 437 Label* miss_label) {
433 AccessorInfo* callback = 0; 438 AccessorInfo* callback = NULL;
434 bool optimize = false; 439 bool optimize = false;
435 // So far the most popular follow ups for interceptor loads are FIELD 440 // So far the most popular follow ups for interceptor loads are FIELD
436 // and CALLBACKS, so inline only them, other cases may be added 441 // and CALLBACKS, so inline only them, other cases may be added
437 // later. 442 // later.
438 if (lookup->type() == FIELD) { 443 if (lookup->type() == FIELD) {
439 optimize = true; 444 optimize = true;
440 } else if (lookup->type() == CALLBACKS) { 445 } else if (lookup->type() == CALLBACKS) {
441 Object* callback_object = lookup->GetCallbackObject(); 446 Object* callback_object = lookup->GetCallbackObject();
442 if (callback_object->IsAccessorInfo()) { 447 if (callback_object->IsAccessorInfo()) {
443 callback = AccessorInfo::cast(callback_object); 448 callback = AccessorInfo::cast(callback_object);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 __ TailCallRuntime(ref, 5, 1); 551 __ TailCallRuntime(ref, 5, 1);
547 } 552 }
548 553
549 private: 554 private:
550 Register name_; 555 Register name_;
551 }; 556 };
552 557
553 558
554 class CallInterceptorCompiler BASE_EMBEDDED { 559 class CallInterceptorCompiler BASE_EMBEDDED {
555 public: 560 public:
556 explicit CallInterceptorCompiler(const ParameterCount& arguments) 561 CallInterceptorCompiler(const ParameterCount& arguments, Register name)
557 : arguments_(arguments), argc_(arguments.immediate()) {} 562 : arguments_(arguments), name_(name) {}
558 563
559 void CompileCacheable(MacroAssembler* masm, 564 void CompileCacheable(MacroAssembler* masm,
560 StubCompiler* stub_compiler, 565 StubCompiler* stub_compiler,
561 Register receiver, 566 Register receiver,
562 Register holder, 567 Register holder,
563 Register scratch1, 568 Register scratch1,
564 Register scratch2, 569 Register scratch2,
565 JSObject* holder_obj, 570 JSObject* holder_obj,
566 LookupResult* lookup, 571 LookupResult* lookup,
567 String* name, 572 String* name,
568 Label* miss_label) { 573 Label* miss_label) {
569 JSFunction* function = 0; 574 JSFunction* function = 0;
570 bool optimize = false; 575 bool optimize = false;
571 // So far the most popular case for failed interceptor is 576 // So far the most popular case for failed interceptor is
572 // CONSTANT_FUNCTION sitting below. 577 // CONSTANT_FUNCTION sitting below.
573 if (lookup->type() == CONSTANT_FUNCTION) { 578 if (lookup->type() == CONSTANT_FUNCTION) {
574 function = lookup->GetConstantFunction(); 579 function = lookup->GetConstantFunction();
575 // JSArray holder is a special case for call constant function 580 // JSArray holder is a special case for call constant function
576 // (see the corresponding code). 581 // (see the corresponding code).
577 if (function->is_compiled() && !holder_obj->IsJSArray()) { 582 if (function->is_compiled() && !holder_obj->IsJSArray()) {
578 optimize = true; 583 optimize = true;
579 } 584 }
580 } 585 }
581 586
582 if (!optimize) { 587 if (!optimize) {
583 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label); 588 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label);
584 return; 589 return;
585 } 590 }
586 591
592 ASSERT(!lookup->holder()->IsGlobalObject());
593
587 __ EnterInternalFrame(); 594 __ EnterInternalFrame();
588 __ push(holder); // save the holder 595 __ push(holder); // Save the holder.
596 __ push(name_); // Save the name.
589 597
590 CompileCallLoadPropertyWithInterceptor( 598 CompileCallLoadPropertyWithInterceptor(masm,
591 masm, 599 receiver,
592 receiver, 600 holder,
593 holder, 601 name_,
594 // Under EnterInternalFrame this refers to name. 602 holder_obj);
595 Operand(rbp, (argc_ + 3) * kPointerSize),
596 holder_obj);
597 603
598 __ pop(receiver); // restore holder 604 __ pop(name_); // Restore the name.
605 __ pop(receiver); // Restore the holder.
599 __ LeaveInternalFrame(); 606 __ LeaveInternalFrame();
600 607
601 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 608 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
602 Label invoke; 609 Label invoke;
603 __ j(not_equal, &invoke); 610 __ j(not_equal, &invoke);
604 611
605 stub_compiler->CheckPrototypes(holder_obj, receiver, 612 stub_compiler->CheckPrototypes(holder_obj, receiver,
606 lookup->holder(), scratch1, 613 lookup->holder(), scratch1,
607 scratch2, 614 scratch2,
608 name, 615 name,
609 miss_label); 616 miss_label);
610 if (lookup->holder()->IsGlobalObject()) {
611 __ movq(rdx, Operand(rsp, (argc_ + 1) * kPointerSize));
612 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
613 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdx);
614 }
615 617
616 ASSERT(function->is_compiled()); 618 __ InvokeFunction(function, arguments_, JUMP_FUNCTION);
617 // Get the function and setup the context.
618 __ Move(rdi, Handle<JSFunction>(function));
619 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
620
621 // Jump to the cached code (tail call).
622 Handle<Code> code(function->code());
623 ParameterCount expected(function->shared()->formal_parameter_count());
624 __ InvokeCode(code, expected, arguments_,
625 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
626 619
627 __ bind(&invoke); 620 __ bind(&invoke);
628 } 621 }
629 622
630 void CompileRegular(MacroAssembler* masm, 623 void CompileRegular(MacroAssembler* masm,
631 Register receiver, 624 Register receiver,
632 Register holder, 625 Register holder,
633 Register scratch, 626 Register scratch,
634 JSObject* holder_obj, 627 JSObject* holder_obj,
635 Label* miss_label) { 628 Label* miss_label) {
636 __ EnterInternalFrame(); 629 __ EnterInternalFrame();
630 // Save the name_ register across the call.
631 __ push(name_);
637 632
638 PushInterceptorArguments(masm, 633 PushInterceptorArguments(masm,
639 receiver, 634 receiver,
640 holder, 635 holder,
641 Operand(rbp, (argc_ + 3) * kPointerSize), 636 name_,
642 holder_obj); 637 holder_obj);
643 638
644 ExternalReference ref = ExternalReference( 639 __ CallExternalReference(
645 IC_Utility(IC::kLoadPropertyWithInterceptorForCall)); 640 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall)),
646 __ movq(rax, Immediate(5)); 641 5);
647 __ movq(rbx, ref);
648 642
649 CEntryStub stub(1); 643 __ pop(name_);
650 __ CallStub(&stub);
651
652 __ LeaveInternalFrame(); 644 __ LeaveInternalFrame();
653 } 645 }
654 646
655 private: 647 private:
656 const ParameterCount& arguments_; 648 const ParameterCount& arguments_;
657 int argc_; 649 Register name_;
658 }; 650 };
659 651
660 652
661 #undef __ 653 #undef __
662 654
663 #define __ ACCESS_MASM((masm())) 655 #define __ ACCESS_MASM((masm()))
664 656
665 657
666 Object* CallStubCompiler::CompileCallConstant(Object* object, 658 Object* CallStubCompiler::CompileCallConstant(Object* object,
667 JSObject* holder, 659 JSObject* holder,
668 JSFunction* function, 660 JSFunction* function,
669 String* name, 661 String* name,
670 StubCompiler::CheckType check) { 662 StubCompiler::CheckType check) {
671 // ----------- S t a t e ------------- 663 // ----------- S t a t e -------------
664 // rcx : function name
665 // rsp[0] : return address
666 // rsp[8] : argument argc
667 // rsp[16] : argument argc - 1
668 // ...
669 // rsp[argc * 8] : argument 1
670 // rsp[(argc + 1) * 8] : argument 0 = receiver
672 // ----------------------------------- 671 // -----------------------------------
673 // rsp[0] return address
674 // rsp[8] argument argc
675 // rsp[16] argument argc - 1
676 // ...
677 // rsp[argc * 8] argument 1
678 // rsp[(argc + 1) * 8] argument 0 = receiver
679 // rsp[(argc + 2) * 8] function name
680 672
681 Label miss; 673 Label miss;
682 674
683 // Get the receiver from the stack. 675 // Get the receiver from the stack.
684 const int argc = arguments().immediate(); 676 const int argc = arguments().immediate();
685 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 677 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
686 678
687 // Check that the receiver isn't a smi. 679 // Check that the receiver isn't a smi.
688 if (check != NUMBER_CHECK) { 680 if (check != NUMBER_CHECK) {
689 __ JumpIfSmi(rdx, &miss); 681 __ JumpIfSmi(rdx, &miss);
690 } 682 }
691 683
692 // Make sure that it's okay not to patch the on stack receiver 684 // Make sure that it's okay not to patch the on stack receiver
693 // unless we're doing a receiver map check. 685 // unless we're doing a receiver map check.
694 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 686 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
695 687
696 switch (check) { 688 switch (check) {
697 case RECEIVER_MAP_CHECK: 689 case RECEIVER_MAP_CHECK:
698 // Check that the maps haven't changed. 690 // Check that the maps haven't changed.
699 CheckPrototypes(JSObject::cast(object), rdx, holder, 691 CheckPrototypes(JSObject::cast(object), rdx, holder,
700 rbx, rcx, name, &miss); 692 rbx, rax, name, &miss);
701 693
702 // Patch the receiver on the stack with the global proxy if 694 // Patch the receiver on the stack with the global proxy if
703 // necessary. 695 // necessary.
704 if (object->IsGlobalObject()) { 696 if (object->IsGlobalObject()) {
705 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 697 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
706 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 698 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
707 } 699 }
708 break; 700 break;
709 701
710 case STRING_CHECK: 702 case STRING_CHECK:
711 if (!function->IsBuiltin()) { 703 if (!function->IsBuiltin()) {
712 // Calling non-builtins with a value as receiver requires boxing. 704 // Calling non-builtins with a value as receiver requires boxing.
713 __ jmp(&miss); 705 __ jmp(&miss);
714 } else { 706 } else {
715 // Check that the object is a two-byte string or a symbol. 707 // Check that the object is a two-byte string or a symbol.
716 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rcx); 708 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
717 __ j(above_equal, &miss); 709 __ j(above_equal, &miss);
718 // Check that the maps starting from the prototype haven't changed. 710 // Check that the maps starting from the prototype haven't changed.
719 GenerateLoadGlobalFunctionPrototype(masm(), 711 GenerateLoadGlobalFunctionPrototype(masm(),
720 Context::STRING_FUNCTION_INDEX, 712 Context::STRING_FUNCTION_INDEX,
721 rcx); 713 rax);
722 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, 714 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
723 rbx, rdx, name, &miss); 715 rbx, rdx, name, &miss);
724 } 716 }
725 break; 717 break;
726 718
727 case NUMBER_CHECK: { 719 case NUMBER_CHECK: {
728 if (!function->IsBuiltin()) { 720 if (!function->IsBuiltin()) {
729 // Calling non-builtins with a value as receiver requires boxing. 721 // Calling non-builtins with a value as receiver requires boxing.
730 __ jmp(&miss); 722 __ jmp(&miss);
731 } else { 723 } else {
732 Label fast; 724 Label fast;
733 // Check that the object is a smi or a heap number. 725 // Check that the object is a smi or a heap number.
734 __ JumpIfSmi(rdx, &fast); 726 __ JumpIfSmi(rdx, &fast);
735 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx); 727 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
736 __ j(not_equal, &miss); 728 __ j(not_equal, &miss);
737 __ bind(&fast); 729 __ bind(&fast);
738 // Check that the maps starting from the prototype haven't changed. 730 // Check that the maps starting from the prototype haven't changed.
739 GenerateLoadGlobalFunctionPrototype(masm(), 731 GenerateLoadGlobalFunctionPrototype(masm(),
740 Context::NUMBER_FUNCTION_INDEX, 732 Context::NUMBER_FUNCTION_INDEX,
741 rcx); 733 rax);
742 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, 734 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
743 rbx, rdx, name, &miss); 735 rbx, rdx, name, &miss);
744 } 736 }
745 break; 737 break;
746 } 738 }
747 739
748 case BOOLEAN_CHECK: { 740 case BOOLEAN_CHECK: {
749 if (!function->IsBuiltin()) { 741 if (!function->IsBuiltin()) {
750 // Calling non-builtins with a value as receiver requires boxing. 742 // Calling non-builtins with a value as receiver requires boxing.
751 __ jmp(&miss); 743 __ jmp(&miss);
752 } else { 744 } else {
753 Label fast; 745 Label fast;
754 // Check that the object is a boolean. 746 // Check that the object is a boolean.
755 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); 747 __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
756 __ j(equal, &fast); 748 __ j(equal, &fast);
757 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); 749 __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
758 __ j(not_equal, &miss); 750 __ j(not_equal, &miss);
759 __ bind(&fast); 751 __ bind(&fast);
760 // Check that the maps starting from the prototype haven't changed. 752 // Check that the maps starting from the prototype haven't changed.
761 GenerateLoadGlobalFunctionPrototype(masm(), 753 GenerateLoadGlobalFunctionPrototype(masm(),
762 Context::BOOLEAN_FUNCTION_INDEX, 754 Context::BOOLEAN_FUNCTION_INDEX,
763 rcx); 755 rax);
764 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, 756 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
765 rbx, rdx, name, &miss); 757 rbx, rdx, name, &miss);
766 } 758 }
767 break; 759 break;
768 } 760 }
769 761
770 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: 762 case JSARRAY_HAS_FAST_ELEMENTS_CHECK:
771 CheckPrototypes(JSObject::cast(object), rdx, holder, 763 CheckPrototypes(JSObject::cast(object), rdx, holder,
772 rbx, rcx, name, &miss); 764 rbx, rax, name, &miss);
773 // Make sure object->HasFastElements(). 765 // Make sure object->HasFastElements().
774 // Get the elements array of the object. 766 // Get the elements array of the object.
775 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 767 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
776 // Check that the object is in fast mode (not dictionary). 768 // Check that the object is in fast mode (not dictionary).
777 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), 769 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
778 Factory::fixed_array_map()); 770 Factory::fixed_array_map());
779 __ j(not_equal, &miss); 771 __ j(not_equal, &miss);
780 break; 772 break;
781 773
782 default: 774 default:
783 UNREACHABLE(); 775 UNREACHABLE();
784 } 776 }
785 777
786 // Get the function and setup the context. 778 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
787 __ Move(rdi, Handle<JSFunction>(function));
788 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
789
790 // Jump to the cached code (tail call).
791 ASSERT(function->is_compiled());
792 Handle<Code> code(function->code());
793 ParameterCount expected(function->shared()->formal_parameter_count());
794 __ InvokeCode(code, expected, arguments(),
795 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
796 779
797 // Handle call cache miss. 780 // Handle call cache miss.
798 __ bind(&miss); 781 __ bind(&miss);
799 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); 782 Handle<Code> ic = ComputeCallMiss(arguments().immediate());
800 __ Jump(ic, RelocInfo::CODE_TARGET); 783 __ Jump(ic, RelocInfo::CODE_TARGET);
801 784
802 // Return the generated code. 785 // Return the generated code.
803 String* function_name = NULL; 786 String* function_name = NULL;
804 if (function->shared()->name()->IsString()) { 787 if (function->shared()->name()->IsString()) {
805 function_name = String::cast(function->shared()->name()); 788 function_name = String::cast(function->shared()->name());
806 } 789 }
807 return GetCode(CONSTANT_FUNCTION, function_name); 790 return GetCode(CONSTANT_FUNCTION, function_name);
808 } 791 }
809 792
810 793
811 Object* CallStubCompiler::CompileCallField(Object* object, 794 Object* CallStubCompiler::CompileCallField(JSObject* object,
812 JSObject* holder, 795 JSObject* holder,
813 int index, 796 int index,
814 String* name) { 797 String* name) {
815 // ----------- S t a t e ------------- 798 // ----------- S t a t e -------------
799 // rcx : function name
800 // rsp[0] : return address
801 // rsp[8] : argument argc
802 // rsp[16] : argument argc - 1
803 // ...
804 // rsp[argc * 8] : argument 1
805 // rsp[(argc + 1) * 8] : argument 0 = receiver
816 // ----------------------------------- 806 // -----------------------------------
817 // rsp[0] return address
818 // rsp[8] argument argc
819 // rsp[16] argument argc - 1
820 // ...
821 // rsp[argc * 8] argument 1
822 // rsp[(argc + 1) * 8] argument 0 = receiver
823 // rsp[(argc + 2) * 8] function name
824 Label miss; 807 Label miss;
825 808
826 // Get the receiver from the stack. 809 // Get the receiver from the stack.
827 const int argc = arguments().immediate(); 810 const int argc = arguments().immediate();
828 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 811 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
829 812
830 // Check that the receiver isn't a smi. 813 // Check that the receiver isn't a smi.
831 __ JumpIfSmi(rdx, &miss); 814 __ JumpIfSmi(rdx, &miss);
832 815
833 // Do the right check and compute the holder register. 816 // Do the right check and compute the holder register.
834 Register reg = 817 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, name, &miss);
835 CheckPrototypes(JSObject::cast(object), rdx, holder,
836 rbx, rcx, name, &miss);
837 818
838 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index); 819 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index);
839 820
840 // Check that the function really is a function. 821 // Check that the function really is a function.
841 __ JumpIfSmi(rdi, &miss); 822 __ JumpIfSmi(rdi, &miss);
842 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); 823 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
843 __ j(not_equal, &miss); 824 __ j(not_equal, &miss);
844 825
845 // Patch the receiver on the stack with the global proxy if 826 // Patch the receiver on the stack with the global proxy if
846 // necessary. 827 // necessary.
847 if (object->IsGlobalObject()) { 828 if (object->IsGlobalObject()) {
848 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 829 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
849 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 830 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
850 } 831 }
851 832
852 // Invoke the function. 833 // Invoke the function.
853 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION); 834 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION);
854 835
855 // Handle call cache miss. 836 // Handle call cache miss.
856 __ bind(&miss); 837 __ bind(&miss);
857 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); 838 Handle<Code> ic = ComputeCallMiss(arguments().immediate());
858 __ Jump(ic, RelocInfo::CODE_TARGET); 839 __ Jump(ic, RelocInfo::CODE_TARGET);
859 840
860 // Return the generated code. 841 // Return the generated code.
861 return GetCode(FIELD, name); 842 return GetCode(FIELD, name);
862 } 843 }
863 844
864 845
865 Object* CallStubCompiler::CompileCallInterceptor(Object* object, 846 Object* CallStubCompiler::CompileCallInterceptor(JSObject* object,
866 JSObject* holder, 847 JSObject* holder,
867 String* name) { 848 String* name) {
868 // ----------- S t a t e ------------- 849 // ----------- S t a t e -------------
850 // rcx : function name
851 // rsp[0] : return address
852 // rsp[8] : argument argc
853 // rsp[16] : argument argc - 1
854 // ...
855 // rsp[argc * 8] : argument 1
856 // rsp[(argc + 1) * 8] : argument 0 = receiver
869 // ----------------------------------- 857 // -----------------------------------
870 Label miss; 858 Label miss;
871 859
872 // Get the number of arguments. 860 // Get the number of arguments.
873 const int argc = arguments().immediate(); 861 const int argc = arguments().immediate();
874 862
875 LookupResult lookup; 863 LookupResult lookup;
876 LookupPostInterceptor(holder, name, &lookup); 864 LookupPostInterceptor(holder, name, &lookup);
877 865
878 // Get the receiver from the stack. 866 // Get the receiver from the stack.
879 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 867 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
880 868
881 CallInterceptorCompiler compiler(arguments()); 869 CallInterceptorCompiler compiler(arguments(), rcx);
882 CompileLoadInterceptor(&compiler, 870 CompileLoadInterceptor(&compiler,
883 this, 871 this,
884 masm(), 872 masm(),
885 JSObject::cast(object), 873 object,
886 holder, 874 holder,
887 name, 875 name,
888 &lookup, 876 &lookup,
889 rdx, 877 rdx,
890 rbx, 878 rbx,
891 rcx, 879 rdi,
892 &miss); 880 &miss);
893 881
894 // Restore receiver. 882 // Restore receiver.
895 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 883 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
896 884
897 // Check that the function really is a function. 885 // Check that the function really is a function.
898 __ JumpIfSmi(rax, &miss); 886 __ JumpIfSmi(rax, &miss);
899 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 887 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
900 __ j(not_equal, &miss); 888 __ j(not_equal, &miss);
901 889
(...skipping 11 matching lines...) Expand all
913 // Handle load cache miss. 901 // Handle load cache miss.
914 __ bind(&miss); 902 __ bind(&miss);
915 Handle<Code> ic = ComputeCallMiss(argc); 903 Handle<Code> ic = ComputeCallMiss(argc);
916 __ Jump(ic, RelocInfo::CODE_TARGET); 904 __ Jump(ic, RelocInfo::CODE_TARGET);
917 905
918 // Return the generated code. 906 // Return the generated code.
919 return GetCode(INTERCEPTOR, name); 907 return GetCode(INTERCEPTOR, name);
920 } 908 }
921 909
922 910
923
924 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, 911 Object* CallStubCompiler::CompileCallGlobal(JSObject* object,
925 GlobalObject* holder, 912 GlobalObject* holder,
926 JSGlobalPropertyCell* cell, 913 JSGlobalPropertyCell* cell,
927 JSFunction* function, 914 JSFunction* function,
928 String* name) { 915 String* name) {
929 // ----------- S t a t e ------------- 916 // ----------- S t a t e -------------
930 // ----------------------------------- 917 // -----------------------------------
931 // rsp[0] return address 918 // rcx : function name
932 // rsp[8] argument argc 919 // rsp[0] : return address
933 // rsp[16] argument argc - 1 920 // rsp[8] : argument argc
921 // rsp[16] : argument argc - 1
934 // ... 922 // ...
935 // rsp[argc * 8] argument 1 923 // rsp[argc * 8] : argument 1
936 // rsp[(argc + 1) * 8] argument 0 = receiver 924 // rsp[(argc + 1) * 8] : argument 0 = receiver
937 // rsp[(argc + 2) * 8] function name
938 Label miss; 925 Label miss;
939 926
940 // Get the number of arguments. 927 // Get the number of arguments.
941 const int argc = arguments().immediate(); 928 const int argc = arguments().immediate();
942 929
943 // Get the receiver from the stack. 930 // Get the receiver from the stack.
944 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 931 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
945 932
946 // If the object is the holder then we know that it's a global 933 // If the object is the holder then we know that it's a global
947 // object which can only happen for contextual calls. In this case, 934 // object which can only happen for contextual calls. In this case,
948 // the receiver cannot be a smi. 935 // the receiver cannot be a smi.
949 if (object != holder) { 936 if (object != holder) {
950 __ JumpIfSmi(rdx, &miss); 937 __ JumpIfSmi(rdx, &miss);
951 } 938 }
952 939
953 // Check that the maps haven't changed. 940 // Check that the maps haven't changed.
954 CheckPrototypes(object, rdx, holder, rbx, rcx, name, &miss); 941 CheckPrototypes(object, rdx, holder, rbx, rax, name, &miss);
955 942
956 // Get the value from the cell. 943 // Get the value from the cell.
957 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); 944 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell));
958 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); 945 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset));
959 946
960 // Check that the cell contains the same function. 947 // Check that the cell contains the same function.
961 if (Heap::InNewSpace(function)) { 948 if (Heap::InNewSpace(function)) {
962 // We can't embed a pointer to a function in new space so we have 949 // We can't embed a pointer to a function in new space so we have
963 // to verify that the shared function info is unchanged. This has 950 // to verify that the shared function info is unchanged. This has
964 // the nice side effect that multiple closures based on the same 951 // the nice side effect that multiple closures based on the same
965 // function can all use this call IC. Before we load through the 952 // function can all use this call IC. Before we load through the
966 // function, we have to verify that it still is a function. 953 // function, we have to verify that it still is a function.
967 __ JumpIfSmi(rdi, &miss); 954 __ JumpIfSmi(rdi, &miss);
968 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 955 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax);
969 __ j(not_equal, &miss); 956 __ j(not_equal, &miss);
970 957
971 // Check the shared function info. Make sure it hasn't changed. 958 // Check the shared function info. Make sure it hasn't changed.
972 __ Move(rcx, Handle<SharedFunctionInfo>(function->shared())); 959 __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
973 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rcx); 960 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
974 __ j(not_equal, &miss); 961 __ j(not_equal, &miss);
975 } else { 962 } else {
976 __ Cmp(rdi, Handle<JSFunction>(function)); 963 __ Cmp(rdi, Handle<JSFunction>(function));
977 __ j(not_equal, &miss); 964 __ j(not_equal, &miss);
978 } 965 }
979 966
980 // Patch the receiver on the stack with the global proxy. 967 // Patch the receiver on the stack with the global proxy.
981 if (object->IsGlobalObject()) { 968 if (object->IsGlobalObject()) {
982 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 969 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
983 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 970 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 Label miss; 1305 Label miss;
1319 1306
1320 __ movq(rax, Operand(rsp, kPointerSize)); 1307 __ movq(rax, Operand(rsp, kPointerSize));
1321 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); 1308 __ movq(rcx, Operand(rsp, 2 * kPointerSize));
1322 __ IncrementCounter(&Counters::keyed_load_string_length, 1); 1309 __ IncrementCounter(&Counters::keyed_load_string_length, 1);
1323 1310
1324 // Check that the name has not changed. 1311 // Check that the name has not changed.
1325 __ Cmp(rax, Handle<String>(name)); 1312 __ Cmp(rax, Handle<String>(name));
1326 __ j(not_equal, &miss); 1313 __ j(not_equal, &miss);
1327 1314
1328 GenerateLoadStringLength(masm(), rcx, rdx, &miss); 1315 GenerateLoadStringLength(masm(), rcx, rdx, rbx, &miss);
1329 __ bind(&miss); 1316 __ bind(&miss);
1330 __ DecrementCounter(&Counters::keyed_load_string_length, 1); 1317 __ DecrementCounter(&Counters::keyed_load_string_length, 1);
1331 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 1318 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
1332 1319
1333 // Return the generated code. 1320 // Return the generated code.
1334 return GetCode(CALLBACKS, name); 1321 return GetCode(CALLBACKS, name);
1335 } 1322 }
1336 1323
1337 1324
1338 Object* StoreStubCompiler::CompileStoreCallback(JSObject* object, 1325 Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 Map* transition, 1377 Map* transition,
1391 String* name) { 1378 String* name) {
1392 // ----------- S t a t e ------------- 1379 // ----------- S t a t e -------------
1393 // -- rax : value 1380 // -- rax : value
1394 // -- rcx : name 1381 // -- rcx : name
1395 // -- rdx : receiver 1382 // -- rdx : receiver
1396 // -- rsp[0] : return address 1383 // -- rsp[0] : return address
1397 // ----------------------------------- 1384 // -----------------------------------
1398 Label miss; 1385 Label miss;
1399 1386
1400 // Generate store field code. Trashes the name register. 1387 // Generate store field code. Preserves receiver and name on jump to miss.
1401 GenerateStoreField(masm(), 1388 GenerateStoreField(masm(),
1402 Builtins::StoreIC_ExtendStorage,
1403 object, 1389 object,
1404 index, 1390 index,
1405 transition, 1391 transition,
1406 rdx, rcx, rbx, 1392 rdx, rcx, rbx,
1407 &miss); 1393 &miss);
1408 1394
1409 // Handle store cache miss. 1395 // Handle store cache miss.
1410 __ bind(&miss); 1396 __ bind(&miss);
1411 __ Move(rcx, Handle<String>(name)); // restore name
1412 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 1397 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
1413 __ Jump(ic, RelocInfo::CODE_TARGET); 1398 __ Jump(ic, RelocInfo::CODE_TARGET);
1414 1399
1415 // Return the generated code. 1400 // Return the generated code.
1416 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 1401 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
1417 } 1402 }
1418 1403
1419 1404
1420 Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 1405 Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
1421 String* name) { 1406 String* name) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 Label miss; 1528 Label miss;
1544 1529
1545 __ IncrementCounter(&Counters::keyed_store_field, 1); 1530 __ IncrementCounter(&Counters::keyed_store_field, 1);
1546 1531
1547 // Get the name from the stack. 1532 // Get the name from the stack.
1548 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); 1533 __ movq(rcx, Operand(rsp, 1 * kPointerSize));
1549 // Check that the name has not changed. 1534 // Check that the name has not changed.
1550 __ Cmp(rcx, Handle<String>(name)); 1535 __ Cmp(rcx, Handle<String>(name));
1551 __ j(not_equal, &miss); 1536 __ j(not_equal, &miss);
1552 1537
1553 // Get the object from the stack. 1538 // Get the receiver from the stack.
1554 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); 1539 __ movq(rdx, Operand(rsp, 2 * kPointerSize));
1555 1540
1556 // Generate store field code. Trashes the name register. 1541 // Generate store field code. Preserves receiver and name on jump to miss.
1557 GenerateStoreField(masm(), 1542 GenerateStoreField(masm(),
1558 Builtins::KeyedStoreIC_ExtendStorage,
1559 object, 1543 object,
1560 index, 1544 index,
1561 transition, 1545 transition,
1562 rbx, rcx, rdx, 1546 rdx, rcx, rbx,
1563 &miss); 1547 &miss);
1564 1548
1565 // Handle store cache miss. 1549 // Handle store cache miss.
1566 __ bind(&miss); 1550 __ bind(&miss);
1567 __ DecrementCounter(&Counters::keyed_store_field, 1); 1551 __ DecrementCounter(&Counters::keyed_store_field, 1);
1568 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 1552 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
1569 __ Jump(ic, RelocInfo::CODE_TARGET); 1553 __ Jump(ic, RelocInfo::CODE_TARGET);
1570 1554
1571 // Return the generated code. 1555 // Return the generated code.
1572 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 1556 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1658 return true; 1642 return true;
1659 } 1643 }
1660 1644
1661 1645
1662 Register StubCompiler::CheckPrototypes(JSObject* object, 1646 Register StubCompiler::CheckPrototypes(JSObject* object,
1663 Register object_reg, 1647 Register object_reg,
1664 JSObject* holder, 1648 JSObject* holder,
1665 Register holder_reg, 1649 Register holder_reg,
1666 Register scratch, 1650 Register scratch,
1667 String* name, 1651 String* name,
1652 int save_at_depth,
1668 Label* miss) { 1653 Label* miss) {
1654 // TODO(602): support object saving.
1655 ASSERT(save_at_depth == kInvalidProtoDepth);
1656
1669 // Check that the maps haven't changed. 1657 // Check that the maps haven't changed.
1670 Register result = 1658 Register result =
1671 __ CheckMaps(object, object_reg, holder, holder_reg, scratch, miss); 1659 __ CheckMaps(object, object_reg, holder, holder_reg, scratch, miss);
1672 1660
1673 // If we've skipped any global objects, it's not enough to verify 1661 // If we've skipped any global objects, it's not enough to verify
1674 // that their maps haven't changed. 1662 // that their maps haven't changed.
1675 while (object != holder) { 1663 while (object != holder) {
1676 if (object->IsGlobalObject()) { 1664 if (object->IsGlobalObject()) {
1677 GlobalObject* global = GlobalObject::cast(object); 1665 GlobalObject* global = GlobalObject::cast(object);
1678 Object* probe = global->EnsurePropertyCell(name); 1666 Object* probe = global->EnsurePropertyCell(name);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1865 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 1853 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
1866 1854
1867 // Return the generated code. 1855 // Return the generated code.
1868 return GetCode(); 1856 return GetCode();
1869 } 1857 }
1870 1858
1871 1859
1872 #undef __ 1860 #undef __
1873 1861
1874 } } // namespace v8::internal 1862 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | src/x64/virtual-frame-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698