| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |