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

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

Issue 502028: Streamline the calling convention of the call ICs by passing the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years 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/ia32/ic-ia32.cc ('k') | src/ia32/virtual-frame-ia32.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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 145
146 // Probe the secondary table. 146 // Probe the secondary table.
147 ProbeTable(masm, flags, kSecondary, name, scratch, extra); 147 ProbeTable(masm, flags, kSecondary, name, scratch, extra);
148 148
149 // Cache miss: Fall-through and let caller handle the miss by 149 // Cache miss: Fall-through and let caller handle the miss by
150 // entering the runtime system. 150 // entering the runtime system.
151 __ bind(&miss); 151 __ bind(&miss);
152 } 152 }
153 153
154 154
155 template <typename Pushable>
156 static void PushInterceptorArguments(MacroAssembler* masm, 155 static void PushInterceptorArguments(MacroAssembler* masm,
157 Register receiver, 156 Register receiver,
158 Register holder, 157 Register holder,
159 Pushable name, 158 Register name,
160 JSObject* holder_obj) { 159 JSObject* holder_obj) {
161 __ push(receiver); 160 __ push(receiver);
162 __ push(holder); 161 __ push(holder);
163 __ push(name); 162 __ push(name);
164 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); 163 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
165 __ mov(receiver, Immediate(Handle<Object>(interceptor))); 164 __ mov(receiver, Immediate(Handle<Object>(interceptor)));
166 __ push(receiver); 165 __ push(receiver);
167 __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset)); 166 __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
168 } 167 }
169 168
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 __ mov(dst, FieldOperand(src, offset)); 277 __ mov(dst, FieldOperand(src, offset));
279 } else { 278 } else {
280 // Calculate the offset into the properties array. 279 // Calculate the offset into the properties array.
281 int offset = index * kPointerSize + FixedArray::kHeaderSize; 280 int offset = index * kPointerSize + FixedArray::kHeaderSize;
282 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 281 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
283 __ mov(dst, FieldOperand(dst, offset)); 282 __ mov(dst, FieldOperand(dst, offset));
284 } 283 }
285 } 284 }
286 285
287 286
288 template <class Pushable>
289 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, 287 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
290 Register receiver, 288 Register receiver,
291 Register holder, 289 Register holder,
292 Pushable name, 290 Register name,
293 JSObject* holder_obj) { 291 JSObject* holder_obj) {
294 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 292 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
295 293
296 ExternalReference ref = 294 ExternalReference ref =
297 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)); 295 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly));
298 __ mov(eax, Immediate(5)); 296 __ mov(eax, Immediate(5));
299 __ mov(ebx, Immediate(ref)); 297 __ mov(ebx, Immediate(ref));
300 298
301 CEntryStub stub(1); 299 CEntryStub stub(1);
302 __ CallStub(&stub); 300 __ CallStub(&stub);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 __ TailCallRuntime(ref, 5, 1); 486 __ TailCallRuntime(ref, 5, 1);
489 } 487 }
490 488
491 private: 489 private:
492 Register name_; 490 Register name_;
493 }; 491 };
494 492
495 493
496 class CallInterceptorCompiler BASE_EMBEDDED { 494 class CallInterceptorCompiler BASE_EMBEDDED {
497 public: 495 public:
498 explicit CallInterceptorCompiler(const ParameterCount& arguments) 496 CallInterceptorCompiler(const ParameterCount& arguments, Register name)
499 : arguments_(arguments), argc_(arguments.immediate()) {} 497 : arguments_(arguments), argc_(arguments.immediate()), name_(name) {}
500 498
501 void CompileCacheable(MacroAssembler* masm, 499 void CompileCacheable(MacroAssembler* masm,
502 StubCompiler* stub_compiler, 500 StubCompiler* stub_compiler,
503 Register receiver, 501 Register receiver,
504 Register holder, 502 Register holder,
505 Register scratch1, 503 Register scratch1,
506 Register scratch2, 504 Register scratch2,
507 JSObject* holder_obj, 505 JSObject* holder_obj,
508 LookupResult* lookup, 506 LookupResult* lookup,
509 String* name, 507 String* name,
(...skipping 10 matching lines...) Expand all
520 optimize = true; 518 optimize = true;
521 } 519 }
522 } 520 }
523 521
524 if (!optimize) { 522 if (!optimize) {
525 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label); 523 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label);
526 return; 524 return;
527 } 525 }
528 526
529 __ EnterInternalFrame(); 527 __ EnterInternalFrame();
530 __ push(holder); // save the holder 528 __ push(holder); // Save the holder.
529 __ push(name_); // Save the name.
531 530
532 CompileCallLoadPropertyWithInterceptor( 531 CompileCallLoadPropertyWithInterceptor(masm,
533 masm, 532 receiver,
534 receiver, 533 holder,
535 holder, 534 name_,
536 // Under EnterInternalFrame this refers to name. 535 holder_obj);
537 Operand(ebp, (argc_ + 3) * kPointerSize),
538 holder_obj);
539 536
540 __ pop(receiver); // restore holder 537 __ pop(name_); // Restore the name.
538 __ pop(receiver); // Restore the holder.
541 __ LeaveInternalFrame(); 539 __ LeaveInternalFrame();
542 540
543 __ cmp(eax, Factory::no_interceptor_result_sentinel()); 541 __ cmp(eax, Factory::no_interceptor_result_sentinel());
544 Label invoke; 542 Label invoke;
545 __ j(not_equal, &invoke); 543 __ j(not_equal, &invoke);
546 544
547 stub_compiler->CheckPrototypes(holder_obj, receiver, 545 stub_compiler->CheckPrototypes(holder_obj, receiver,
548 lookup->holder(), scratch1, 546 lookup->holder(), scratch1,
549 scratch2, 547 scratch2,
550 name, 548 name,
(...skipping 19 matching lines...) Expand all
570 __ bind(&invoke); 568 __ bind(&invoke);
571 } 569 }
572 570
573 void CompileRegular(MacroAssembler* masm, 571 void CompileRegular(MacroAssembler* masm,
574 Register receiver, 572 Register receiver,
575 Register holder, 573 Register holder,
576 Register scratch, 574 Register scratch,
577 JSObject* holder_obj, 575 JSObject* holder_obj,
578 Label* miss_label) { 576 Label* miss_label) {
579 __ EnterInternalFrame(); 577 __ EnterInternalFrame();
578 // Save the name_ register across the call.
579 __ push(name_);
580 580
581 PushInterceptorArguments(masm, 581 PushInterceptorArguments(masm,
582 receiver, 582 receiver,
583 holder, 583 holder,
584 Operand(ebp, (argc_ + 3) * kPointerSize), 584 name_,
585 holder_obj); 585 holder_obj);
586 586
587 ExternalReference ref = ExternalReference( 587 ExternalReference ref = ExternalReference(
588 IC_Utility(IC::kLoadPropertyWithInterceptorForCall)); 588 IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
589 __ mov(eax, Immediate(5)); 589 __ mov(eax, Immediate(5));
590 __ mov(ebx, Immediate(ref)); 590 __ mov(ebx, Immediate(ref));
591 591
592 CEntryStub stub(1); 592 CEntryStub stub(1);
593 __ CallStub(&stub); 593 __ CallStub(&stub);
594 594
595 // Restore the name_ register.
596 __ pop(name_);
595 __ LeaveInternalFrame(); 597 __ LeaveInternalFrame();
596 } 598 }
597 599
598 private: 600 private:
599 const ParameterCount& arguments_; 601 const ParameterCount& arguments_;
600 int argc_; 602 int argc_;
603 Register name_;
601 }; 604 };
602 605
603 606
604 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 607 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
605 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 608 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
606 Code* code = NULL; 609 Code* code = NULL;
607 if (kind == Code::LOAD_IC) { 610 if (kind == Code::LOAD_IC) {
608 code = Builtins::builtin(Builtins::LoadIC_Miss); 611 code = Builtins::builtin(Builtins::LoadIC_Miss);
609 } else { 612 } else {
610 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); 613 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss);
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 890
888 return GetCodeWithFlags(flags, "LazyCompileStub"); 891 return GetCodeWithFlags(flags, "LazyCompileStub");
889 } 892 }
890 893
891 894
892 Object* CallStubCompiler::CompileCallField(Object* object, 895 Object* CallStubCompiler::CompileCallField(Object* object,
893 JSObject* holder, 896 JSObject* holder,
894 int index, 897 int index,
895 String* name) { 898 String* name) {
896 // ----------- S t a t e ------------- 899 // ----------- S t a t e -------------
900 // -- ecx : name
901 // -- esp[0] : return address
902 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
903 // -- ...
904 // -- esp[(argc + 1) * 4] : receiver
897 // ----------------------------------- 905 // -----------------------------------
898 Label miss; 906 Label miss;
899 907
900 // Get the receiver from the stack. 908 // Get the receiver from the stack.
901 const int argc = arguments().immediate(); 909 const int argc = arguments().immediate();
902 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 910 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
903 911
904 // Check that the receiver isn't a smi. 912 // Check that the receiver isn't a smi.
905 __ test(edx, Immediate(kSmiTagMask)); 913 __ test(edx, Immediate(kSmiTagMask));
906 __ j(zero, &miss, not_taken); 914 __ j(zero, &miss, not_taken);
907 915
908 // Do the right check and compute the holder register. 916 // Do the right check and compute the holder register.
909 Register reg = 917 Register reg =
910 CheckPrototypes(JSObject::cast(object), edx, holder, 918 CheckPrototypes(JSObject::cast(object), edx, holder,
911 ebx, ecx, name, &miss); 919 ebx, eax, name, &miss);
912 920
913 GenerateFastPropertyLoad(masm(), edi, reg, holder, index); 921 GenerateFastPropertyLoad(masm(), edi, reg, holder, index);
914 922
915 // Check that the function really is a function. 923 // Check that the function really is a function.
916 __ test(edi, Immediate(kSmiTagMask)); 924 __ test(edi, Immediate(kSmiTagMask));
917 __ j(zero, &miss, not_taken); 925 __ j(zero, &miss, not_taken);
918 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 926 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
919 __ j(not_equal, &miss, not_taken); 927 __ j(not_equal, &miss, not_taken);
920 928
921 // Patch the receiver on the stack with the global proxy if 929 // Patch the receiver on the stack with the global proxy if
(...skipping 15 matching lines...) Expand all
937 return GetCode(FIELD, name); 945 return GetCode(FIELD, name);
938 } 946 }
939 947
940 948
941 Object* CallStubCompiler::CompileCallConstant(Object* object, 949 Object* CallStubCompiler::CompileCallConstant(Object* object,
942 JSObject* holder, 950 JSObject* holder,
943 JSFunction* function, 951 JSFunction* function,
944 String* name, 952 String* name,
945 CheckType check) { 953 CheckType check) {
946 // ----------- S t a t e ------------- 954 // ----------- S t a t e -------------
955 // -- ecx : name
956 // -- esp[0] : return address
957 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
958 // -- ...
959 // -- esp[(argc + 1) * 4] : receiver
947 // ----------------------------------- 960 // -----------------------------------
948 Label miss; 961 Label miss;
949 962
950 // Get the receiver from the stack. 963 // Get the receiver from the stack.
951 const int argc = arguments().immediate(); 964 const int argc = arguments().immediate();
952 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 965 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
953 966
954 // Check that the receiver isn't a smi. 967 // Check that the receiver isn't a smi.
955 if (check != NUMBER_CHECK) { 968 if (check != NUMBER_CHECK) {
956 __ test(edx, Immediate(kSmiTagMask)); 969 __ test(edx, Immediate(kSmiTagMask));
957 __ j(zero, &miss, not_taken); 970 __ j(zero, &miss, not_taken);
958 } 971 }
959 972
960 // Make sure that it's okay not to patch the on stack receiver 973 // Make sure that it's okay not to patch the on stack receiver
961 // unless we're doing a receiver map check. 974 // unless we're doing a receiver map check.
962 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 975 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
963 976
964 switch (check) { 977 switch (check) {
965 case RECEIVER_MAP_CHECK: 978 case RECEIVER_MAP_CHECK:
966 // Check that the maps haven't changed. 979 // Check that the maps haven't changed.
967 CheckPrototypes(JSObject::cast(object), edx, holder, 980 CheckPrototypes(JSObject::cast(object), edx, holder,
968 ebx, ecx, name, &miss); 981 ebx, eax, name, &miss);
969 982
970 // Patch the receiver on the stack with the global proxy if 983 // Patch the receiver on the stack with the global proxy if
971 // necessary. 984 // necessary.
972 if (object->IsGlobalObject()) { 985 if (object->IsGlobalObject()) {
973 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 986 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
974 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 987 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
975 } 988 }
976 break; 989 break;
977 990
978 case STRING_CHECK: 991 case STRING_CHECK:
979 // Check that the object is a two-byte string or a symbol. 992 // Check that the object is a two-byte string or a symbol.
980 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 993 __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset));
981 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 994 __ movzx_b(eax, FieldOperand(ecx, Map::kInstanceTypeOffset));
982 __ cmp(ecx, FIRST_NONSTRING_TYPE); 995 __ cmp(eax, FIRST_NONSTRING_TYPE);
983 __ j(above_equal, &miss, not_taken); 996 __ j(above_equal, &miss, not_taken);
984 // Check that the maps starting from the prototype haven't changed. 997 // Check that the maps starting from the prototype haven't changed.
985 GenerateLoadGlobalFunctionPrototype(masm(), 998 GenerateLoadGlobalFunctionPrototype(masm(),
986 Context::STRING_FUNCTION_INDEX, 999 Context::STRING_FUNCTION_INDEX,
987 ecx); 1000 eax);
988 CheckPrototypes(JSObject::cast(object->GetPrototype()), ecx, holder, 1001 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
989 ebx, edx, name, &miss); 1002 ebx, edx, name, &miss);
990 break; 1003 break;
991 1004
992 case NUMBER_CHECK: { 1005 case NUMBER_CHECK: {
993 Label fast; 1006 Label fast;
994 // Check that the object is a smi or a heap number. 1007 // Check that the object is a smi or a heap number.
995 __ test(edx, Immediate(kSmiTagMask)); 1008 __ test(edx, Immediate(kSmiTagMask));
996 __ j(zero, &fast, taken); 1009 __ j(zero, &fast, taken);
997 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx); 1010 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax);
998 __ j(not_equal, &miss, not_taken); 1011 __ j(not_equal, &miss, not_taken);
999 __ bind(&fast); 1012 __ bind(&fast);
1000 // Check that the maps starting from the prototype haven't changed. 1013 // Check that the maps starting from the prototype haven't changed.
1001 GenerateLoadGlobalFunctionPrototype(masm(), 1014 GenerateLoadGlobalFunctionPrototype(masm(),
1002 Context::NUMBER_FUNCTION_INDEX, 1015 Context::NUMBER_FUNCTION_INDEX,
1003 ecx); 1016 eax);
1004 CheckPrototypes(JSObject::cast(object->GetPrototype()), ecx, holder, 1017 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
1005 ebx, edx, name, &miss); 1018 ebx, edx, name, &miss);
1006 break; 1019 break;
1007 } 1020 }
1008 1021
1009 case BOOLEAN_CHECK: { 1022 case BOOLEAN_CHECK: {
1010 Label fast; 1023 Label fast;
1011 // Check that the object is a boolean. 1024 // Check that the object is a boolean.
1012 __ cmp(edx, Factory::true_value()); 1025 __ cmp(edx, Factory::true_value());
1013 __ j(equal, &fast, taken); 1026 __ j(equal, &fast, taken);
1014 __ cmp(edx, Factory::false_value()); 1027 __ cmp(edx, Factory::false_value());
1015 __ j(not_equal, &miss, not_taken); 1028 __ j(not_equal, &miss, not_taken);
1016 __ bind(&fast); 1029 __ bind(&fast);
1017 // Check that the maps starting from the prototype haven't changed. 1030 // Check that the maps starting from the prototype haven't changed.
1018 GenerateLoadGlobalFunctionPrototype(masm(), 1031 GenerateLoadGlobalFunctionPrototype(masm(),
1019 Context::BOOLEAN_FUNCTION_INDEX, 1032 Context::BOOLEAN_FUNCTION_INDEX,
1020 ecx); 1033 eax);
1021 CheckPrototypes(JSObject::cast(object->GetPrototype()), ecx, holder, 1034 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
1022 ebx, edx, name, &miss); 1035 ebx, edx, name, &miss);
1023 break; 1036 break;
1024 } 1037 }
1025 1038
1026 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: 1039 case JSARRAY_HAS_FAST_ELEMENTS_CHECK:
1027 CheckPrototypes(JSObject::cast(object), edx, holder, 1040 CheckPrototypes(JSObject::cast(object), edx, holder,
1028 ebx, ecx, name, &miss); 1041 ebx, eax, name, &miss);
1029 // Make sure object->HasFastElements(). 1042 // Make sure object->HasFastElements().
1030 // Get the elements array of the object. 1043 // Get the elements array of the object.
1031 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 1044 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
1032 // Check that the object is in fast mode (not dictionary). 1045 // Check that the object is in fast mode (not dictionary).
1033 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1046 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1034 Immediate(Factory::fixed_array_map())); 1047 Immediate(Factory::fixed_array_map()));
1035 __ j(not_equal, &miss, not_taken); 1048 __ j(not_equal, &miss, not_taken);
1036 break; 1049 break;
1037 1050
1038 default: 1051 default:
(...skipping 22 matching lines...) Expand all
1061 function_name = String::cast(function->shared()->name()); 1074 function_name = String::cast(function->shared()->name());
1062 } 1075 }
1063 return GetCode(CONSTANT_FUNCTION, function_name); 1076 return GetCode(CONSTANT_FUNCTION, function_name);
1064 } 1077 }
1065 1078
1066 1079
1067 Object* CallStubCompiler::CompileCallInterceptor(Object* object, 1080 Object* CallStubCompiler::CompileCallInterceptor(Object* object,
1068 JSObject* holder, 1081 JSObject* holder,
1069 String* name) { 1082 String* name) {
1070 // ----------- S t a t e ------------- 1083 // ----------- S t a t e -------------
1084 // -- ecx : name
1085 // -- esp[0] : return address
1086 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1087 // -- ...
1088 // -- esp[(argc + 1) * 4] : receiver
1071 // ----------------------------------- 1089 // -----------------------------------
1072 Label miss; 1090 Label miss;
1073 1091
1074 // Get the number of arguments. 1092 // Get the number of arguments.
1075 const int argc = arguments().immediate(); 1093 const int argc = arguments().immediate();
1076 1094
1077 LookupResult lookup; 1095 LookupResult lookup;
1078 LookupPostInterceptor(holder, name, &lookup); 1096 LookupPostInterceptor(holder, name, &lookup);
1079 1097
1080 // Get the receiver from the stack. 1098 // Get the receiver from the stack.
1081 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1099 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1082 1100
1083 CallInterceptorCompiler compiler(arguments()); 1101 CallInterceptorCompiler compiler(arguments(), ecx);
1084 CompileLoadInterceptor(&compiler, 1102 CompileLoadInterceptor(&compiler,
1085 this, 1103 this,
1086 masm(), 1104 masm(),
1087 JSObject::cast(object), 1105 JSObject::cast(object),
1088 holder, 1106 holder,
1089 name, 1107 name,
1090 &lookup, 1108 &lookup,
1091 edx, 1109 edx,
1092 ebx, 1110 ebx,
1093 ecx, 1111 edi,
1094 &miss); 1112 &miss);
1095 1113
1096 // Restore receiver. 1114 // Restore receiver.
1097 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1115 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1098 1116
1099 // Check that the function really is a function. 1117 // Check that the function really is a function.
1100 __ test(eax, Immediate(kSmiTagMask)); 1118 __ test(eax, Immediate(kSmiTagMask));
1101 __ j(zero, &miss, not_taken); 1119 __ j(zero, &miss, not_taken);
1102 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 1120 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
1103 __ j(not_equal, &miss, not_taken); 1121 __ j(not_equal, &miss, not_taken);
(...skipping 18 matching lines...) Expand all
1122 return GetCode(INTERCEPTOR, name); 1140 return GetCode(INTERCEPTOR, name);
1123 } 1141 }
1124 1142
1125 1143
1126 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, 1144 Object* CallStubCompiler::CompileCallGlobal(JSObject* object,
1127 GlobalObject* holder, 1145 GlobalObject* holder,
1128 JSGlobalPropertyCell* cell, 1146 JSGlobalPropertyCell* cell,
1129 JSFunction* function, 1147 JSFunction* function,
1130 String* name) { 1148 String* name) {
1131 // ----------- S t a t e ------------- 1149 // ----------- S t a t e -------------
1150 // -- ecx : name
1151 // -- esp[0] : return address
1152 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1153 // -- ...
1154 // -- esp[(argc + 1) * 4] : receiver
1132 // ----------------------------------- 1155 // -----------------------------------
1133 Label miss; 1156 Label miss;
1134 1157
1135 // Get the number of arguments. 1158 // Get the number of arguments.
1136 const int argc = arguments().immediate(); 1159 const int argc = arguments().immediate();
1137 1160
1138 // Get the receiver from the stack. 1161 // Get the receiver from the stack.
1139 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1162 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1140 1163
1141 // If the object is the holder then we know that it's a global 1164 // If the object is the holder then we know that it's a global
1142 // object which can only happen for contextual calls. In this case, 1165 // object which can only happen for contextual calls. In this case,
1143 // the receiver cannot be a smi. 1166 // the receiver cannot be a smi.
1144 if (object != holder) { 1167 if (object != holder) {
1145 __ test(edx, Immediate(kSmiTagMask)); 1168 __ test(edx, Immediate(kSmiTagMask));
1146 __ j(zero, &miss, not_taken); 1169 __ j(zero, &miss, not_taken);
1147 } 1170 }
1148 1171
1149 // Check that the maps haven't changed. 1172 // Check that the maps haven't changed.
1150 CheckPrototypes(object, edx, holder, ebx, ecx, name, &miss); 1173 CheckPrototypes(object, edx, holder, ebx, eax, name, &miss);
1151 1174
1152 // Get the value from the cell. 1175 // Get the value from the cell.
1153 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); 1176 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell)));
1154 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); 1177 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset));
1155 1178
1156 // Check that the cell contains the same function. 1179 // Check that the cell contains the same function.
1157 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); 1180 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function)));
1158 __ j(not_equal, &miss, not_taken); 1181 __ j(not_equal, &miss, not_taken);
1159 1182
1160 // Patch the receiver on the stack with the global proxy. 1183 // Patch the receiver on the stack with the global proxy.
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
1898 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 1921 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
1899 1922
1900 // Return the generated code. 1923 // Return the generated code.
1901 return GetCode(); 1924 return GetCode();
1902 } 1925 }
1903 1926
1904 1927
1905 #undef __ 1928 #undef __
1906 1929
1907 } } // namespace v8::internal 1930 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/virtual-frame-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698