| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 __ jmp(kScratchRegister); | 103 __ jmp(kScratchRegister); |
| 104 | 104 |
| 105 __ bind(&miss); | 105 __ bind(&miss); |
| 106 } | 106 } |
| 107 | 107 |
| 108 | 108 |
| 109 // Helper function used to check that the dictionary doesn't contain | 109 // Helper function used to check that the dictionary doesn't contain |
| 110 // the property. This function may return false negatives, so miss_label | 110 // the property. This function may return false negatives, so miss_label |
| 111 // must always call a backup property check that is complete. | 111 // must always call a backup property check that is complete. |
| 112 // This function is safe to call if the receiver has fast properties. | 112 // This function is safe to call if the receiver has fast properties. |
| 113 // Name must be an internalized string and receiver must be a heap object. | 113 // Name must be unique and receiver must be a heap object. |
| 114 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 114 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
| 115 Label* miss_label, | 115 Label* miss_label, |
| 116 Register receiver, | 116 Register receiver, |
| 117 Handle<String> name, | 117 Handle<Name> name, |
| 118 Register r0, | 118 Register r0, |
| 119 Register r1) { | 119 Register r1) { |
| 120 ASSERT(name->IsInternalizedString()); | 120 ASSERT(name->IsUniqueName()); |
| 121 Counters* counters = masm->isolate()->counters(); | 121 Counters* counters = masm->isolate()->counters(); |
| 122 __ IncrementCounter(counters->negative_lookups(), 1); | 122 __ IncrementCounter(counters->negative_lookups(), 1); |
| 123 __ IncrementCounter(counters->negative_lookups_miss(), 1); | 123 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
| 124 | 124 |
| 125 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 125 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 126 | 126 |
| 127 const int kInterceptorOrAccessCheckNeededMask = | 127 const int kInterceptorOrAccessCheckNeededMask = |
| 128 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 128 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
| 129 | 129 |
| 130 // Bail out if the receiver has a named interceptor or requires access checks. | 130 // Bail out if the receiver has a named interceptor or requires access checks. |
| 131 __ testb(FieldOperand(r0, Map::kBitFieldOffset), | 131 __ testb(FieldOperand(r0, Map::kBitFieldOffset), |
| 132 Immediate(kInterceptorOrAccessCheckNeededMask)); | 132 Immediate(kInterceptorOrAccessCheckNeededMask)); |
| 133 __ j(not_zero, miss_label); | 133 __ j(not_zero, miss_label); |
| 134 | 134 |
| 135 // Check that receiver is a JSObject. | 135 // Check that receiver is a JSObject. |
| 136 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); | 136 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); |
| 137 __ j(below, miss_label); | 137 __ j(below, miss_label); |
| 138 | 138 |
| 139 // Load properties array. | 139 // Load properties array. |
| 140 Register properties = r0; | 140 Register properties = r0; |
| 141 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 141 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
| 142 | 142 |
| 143 // Check that the properties array is a dictionary. | 143 // Check that the properties array is a dictionary. |
| 144 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), | 144 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), |
| 145 Heap::kHashTableMapRootIndex); | 145 Heap::kHashTableMapRootIndex); |
| 146 __ j(not_equal, miss_label); | 146 __ j(not_equal, miss_label); |
| 147 | 147 |
| 148 Label done; | 148 Label done; |
| 149 StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 149 NameDictionaryLookupStub::GenerateNegativeLookup(masm, |
| 150 miss_label, | 150 miss_label, |
| 151 &done, | 151 &done, |
| 152 properties, | 152 properties, |
| 153 name, | 153 name, |
| 154 r1); | 154 r1); |
| 155 __ bind(&done); | 155 __ bind(&done); |
| 156 __ DecrementCounter(counters->negative_lookups_miss(), 1); | 156 __ DecrementCounter(counters->negative_lookups_miss(), 1); |
| 157 } | 157 } |
| 158 | 158 |
| 159 | 159 |
| 160 void StubCache::GenerateProbe(MacroAssembler* masm, | 160 void StubCache::GenerateProbe(MacroAssembler* masm, |
| 161 Code::Flags flags, | 161 Code::Flags flags, |
| 162 Register receiver, | 162 Register receiver, |
| 163 Register name, | 163 Register name, |
| 164 Register scratch, | 164 Register scratch, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 186 ASSERT(extra2.is(no_reg)); | 186 ASSERT(extra2.is(no_reg)); |
| 187 ASSERT(extra3.is(no_reg)); | 187 ASSERT(extra3.is(no_reg)); |
| 188 | 188 |
| 189 Counters* counters = masm->isolate()->counters(); | 189 Counters* counters = masm->isolate()->counters(); |
| 190 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); | 190 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); |
| 191 | 191 |
| 192 // Check that the receiver isn't a smi. | 192 // Check that the receiver isn't a smi. |
| 193 __ JumpIfSmi(receiver, &miss); | 193 __ JumpIfSmi(receiver, &miss); |
| 194 | 194 |
| 195 // Get the map of the receiver and compute the hash. | 195 // Get the map of the receiver and compute the hash. |
| 196 __ movl(scratch, FieldOperand(name, String::kHashFieldOffset)); | 196 __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset)); |
| 197 // Use only the low 32 bits of the map pointer. | 197 // Use only the low 32 bits of the map pointer. |
| 198 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 198 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 199 __ xor_(scratch, Immediate(flags)); | 199 __ xor_(scratch, Immediate(flags)); |
| 200 // We mask out the last two bits because they are not part of the hash and | 200 // We mask out the last two bits because they are not part of the hash and |
| 201 // they are always 01 for maps. Also in the two 'and' instructions below. | 201 // they are always 01 for maps. Also in the two 'and' instructions below. |
| 202 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); | 202 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
| 203 | 203 |
| 204 // Probe the primary table. | 204 // Probe the primary table. |
| 205 ProbeTable(isolate, masm, flags, kPrimary, receiver, name, scratch); | 205 ProbeTable(isolate, masm, flags, kPrimary, receiver, name, scratch); |
| 206 | 206 |
| 207 // Primary miss: Compute hash for secondary probe. | 207 // Primary miss: Compute hash for secondary probe. |
| 208 __ movl(scratch, FieldOperand(name, String::kHashFieldOffset)); | 208 __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset)); |
| 209 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 209 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 210 __ xor_(scratch, Immediate(flags)); | 210 __ xor_(scratch, Immediate(flags)); |
| 211 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); | 211 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
| 212 __ subl(scratch, name); | 212 __ subl(scratch, name); |
| 213 __ addl(scratch, Immediate(flags)); | 213 __ addl(scratch, Immediate(flags)); |
| 214 __ and_(scratch, Immediate((kSecondaryTableSize - 1) << kHeapObjectTagSize)); | 214 __ and_(scratch, Immediate((kSecondaryTableSize - 1) << kHeapObjectTagSize)); |
| 215 | 215 |
| 216 // Probe the secondary table. | 216 // Probe the secondary table. |
| 217 ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch); | 217 ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch); |
| 218 | 218 |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 Register name, | 525 Register name, |
| 526 Code::ExtraICState extra_ic_state) | 526 Code::ExtraICState extra_ic_state) |
| 527 : stub_compiler_(stub_compiler), | 527 : stub_compiler_(stub_compiler), |
| 528 arguments_(arguments), | 528 arguments_(arguments), |
| 529 name_(name), | 529 name_(name), |
| 530 extra_ic_state_(extra_ic_state) {} | 530 extra_ic_state_(extra_ic_state) {} |
| 531 | 531 |
| 532 void Compile(MacroAssembler* masm, | 532 void Compile(MacroAssembler* masm, |
| 533 Handle<JSObject> object, | 533 Handle<JSObject> object, |
| 534 Handle<JSObject> holder, | 534 Handle<JSObject> holder, |
| 535 Handle<String> name, | 535 Handle<Name> name, |
| 536 LookupResult* lookup, | 536 LookupResult* lookup, |
| 537 Register receiver, | 537 Register receiver, |
| 538 Register scratch1, | 538 Register scratch1, |
| 539 Register scratch2, | 539 Register scratch2, |
| 540 Register scratch3, | 540 Register scratch3, |
| 541 Label* miss) { | 541 Label* miss) { |
| 542 ASSERT(holder->HasNamedInterceptor()); | 542 ASSERT(holder->HasNamedInterceptor()); |
| 543 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 543 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
| 544 | 544 |
| 545 // Check that the receiver isn't a smi. | 545 // Check that the receiver isn't a smi. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 557 | 557 |
| 558 private: | 558 private: |
| 559 void CompileCacheable(MacroAssembler* masm, | 559 void CompileCacheable(MacroAssembler* masm, |
| 560 Handle<JSObject> object, | 560 Handle<JSObject> object, |
| 561 Register receiver, | 561 Register receiver, |
| 562 Register scratch1, | 562 Register scratch1, |
| 563 Register scratch2, | 563 Register scratch2, |
| 564 Register scratch3, | 564 Register scratch3, |
| 565 Handle<JSObject> interceptor_holder, | 565 Handle<JSObject> interceptor_holder, |
| 566 LookupResult* lookup, | 566 LookupResult* lookup, |
| 567 Handle<String> name, | 567 Handle<Name> name, |
| 568 const CallOptimization& optimization, | 568 const CallOptimization& optimization, |
| 569 Label* miss_label) { | 569 Label* miss_label) { |
| 570 ASSERT(optimization.is_constant_call()); | 570 ASSERT(optimization.is_constant_call()); |
| 571 ASSERT(!lookup->holder()->IsGlobalObject()); | 571 ASSERT(!lookup->holder()->IsGlobalObject()); |
| 572 | 572 |
| 573 int depth1 = kInvalidProtoDepth; | 573 int depth1 = kInvalidProtoDepth; |
| 574 int depth2 = kInvalidProtoDepth; | 574 int depth2 = kInvalidProtoDepth; |
| 575 bool can_do_fast_api_call = false; | 575 bool can_do_fast_api_call = false; |
| 576 if (optimization.is_simple_api_call() && | 576 if (optimization.is_simple_api_call() && |
| 577 !lookup->holder()->IsGlobalObject()) { | 577 !lookup->holder()->IsGlobalObject()) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 FreeSpaceForFastApiCall(masm, scratch1); | 650 FreeSpaceForFastApiCall(masm, scratch1); |
| 651 } | 651 } |
| 652 } | 652 } |
| 653 | 653 |
| 654 void CompileRegular(MacroAssembler* masm, | 654 void CompileRegular(MacroAssembler* masm, |
| 655 Handle<JSObject> object, | 655 Handle<JSObject> object, |
| 656 Register receiver, | 656 Register receiver, |
| 657 Register scratch1, | 657 Register scratch1, |
| 658 Register scratch2, | 658 Register scratch2, |
| 659 Register scratch3, | 659 Register scratch3, |
| 660 Handle<String> name, | 660 Handle<Name> name, |
| 661 Handle<JSObject> interceptor_holder, | 661 Handle<JSObject> interceptor_holder, |
| 662 Label* miss_label) { | 662 Label* miss_label) { |
| 663 Register holder = | 663 Register holder = |
| 664 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 664 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, |
| 665 scratch1, scratch2, scratch3, | 665 scratch1, scratch2, scratch3, |
| 666 name, miss_label); | 666 name, miss_label); |
| 667 | 667 |
| 668 FrameScope scope(masm, StackFrame::INTERNAL); | 668 FrameScope scope(masm, StackFrame::INTERNAL); |
| 669 // Save the name_ register across the call. | 669 // Save the name_ register across the call. |
| 670 __ push(name_); | 670 __ push(name_); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 __ Jump(code, RelocInfo::CODE_TARGET); | 738 __ Jump(code, RelocInfo::CODE_TARGET); |
| 739 } | 739 } |
| 740 | 740 |
| 741 | 741 |
| 742 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 742 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
| 743 // but may be destroyed if store is successful. | 743 // but may be destroyed if store is successful. |
| 744 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 744 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| 745 Handle<JSObject> object, | 745 Handle<JSObject> object, |
| 746 int index, | 746 int index, |
| 747 Handle<Map> transition, | 747 Handle<Map> transition, |
| 748 Handle<String> name, | 748 Handle<Name> name, |
| 749 Register receiver_reg, | 749 Register receiver_reg, |
| 750 Register name_reg, | 750 Register name_reg, |
| 751 Register scratch1, | 751 Register scratch1, |
| 752 Register scratch2, | 752 Register scratch2, |
| 753 Label* miss_label) { | 753 Label* miss_label) { |
| 754 LookupResult lookup(masm->isolate()); | 754 LookupResult lookup(masm->isolate()); |
| 755 object->Lookup(*name, &lookup); | 755 object->Lookup(*name, &lookup); |
| 756 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { | 756 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { |
| 757 // In sloppy mode, we could just return the value and be done. However, we | 757 // In sloppy mode, we could just return the value and be done. However, we |
| 758 // might be in strict mode, where we have to throw. Since we cannot tell, | 758 // might be in strict mode, where we have to throw. Since we cannot tell, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 // Return the value (register rax). | 866 // Return the value (register rax). |
| 867 __ ret(0); | 867 __ ret(0); |
| 868 } | 868 } |
| 869 | 869 |
| 870 | 870 |
| 871 // Generate code to check that a global property cell is empty. Create | 871 // Generate code to check that a global property cell is empty. Create |
| 872 // the property cell at compilation time if no cell exists for the | 872 // the property cell at compilation time if no cell exists for the |
| 873 // property. | 873 // property. |
| 874 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 874 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 875 Handle<GlobalObject> global, | 875 Handle<GlobalObject> global, |
| 876 Handle<String> name, | 876 Handle<Name> name, |
| 877 Register scratch, | 877 Register scratch, |
| 878 Label* miss) { | 878 Label* miss) { |
| 879 Handle<JSGlobalPropertyCell> cell = | 879 Handle<JSGlobalPropertyCell> cell = |
| 880 GlobalObject::EnsurePropertyCell(global, name); | 880 GlobalObject::EnsurePropertyCell(global, name); |
| 881 ASSERT(cell->value()->IsTheHole()); | 881 ASSERT(cell->value()->IsTheHole()); |
| 882 __ Move(scratch, cell); | 882 __ Move(scratch, cell); |
| 883 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 883 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
| 884 masm->isolate()->factory()->the_hole_value()); | 884 masm->isolate()->factory()->the_hole_value()); |
| 885 __ j(not_equal, miss); | 885 __ j(not_equal, miss); |
| 886 } | 886 } |
| 887 | 887 |
| 888 | 888 |
| 889 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 889 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
| 890 // from object to (but not including) holder. | 890 // from object to (but not including) holder. |
| 891 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 891 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
| 892 Handle<JSObject> object, | 892 Handle<JSObject> object, |
| 893 Handle<JSObject> holder, | 893 Handle<JSObject> holder, |
| 894 Handle<String> name, | 894 Handle<Name> name, |
| 895 Register scratch, | 895 Register scratch, |
| 896 Label* miss) { | 896 Label* miss) { |
| 897 Handle<JSObject> current = object; | 897 Handle<JSObject> current = object; |
| 898 while (!current.is_identical_to(holder)) { | 898 while (!current.is_identical_to(holder)) { |
| 899 if (current->IsGlobalObject()) { | 899 if (current->IsGlobalObject()) { |
| 900 GenerateCheckPropertyCell(masm, | 900 GenerateCheckPropertyCell(masm, |
| 901 Handle<GlobalObject>::cast(current), | 901 Handle<GlobalObject>::cast(current), |
| 902 name, | 902 name, |
| 903 scratch, | 903 scratch, |
| 904 miss); | 904 miss); |
| 905 } | 905 } |
| 906 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | 906 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); |
| 907 } | 907 } |
| 908 } | 908 } |
| 909 | 909 |
| 910 #undef __ | 910 #undef __ |
| 911 #define __ ACCESS_MASM((masm())) | 911 #define __ ACCESS_MASM((masm())) |
| 912 | 912 |
| 913 | 913 |
| 914 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 914 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 915 Register object_reg, | 915 Register object_reg, |
| 916 Handle<JSObject> holder, | 916 Handle<JSObject> holder, |
| 917 Register holder_reg, | 917 Register holder_reg, |
| 918 Register scratch1, | 918 Register scratch1, |
| 919 Register scratch2, | 919 Register scratch2, |
| 920 Handle<String> name, | 920 Handle<Name> name, |
| 921 int save_at_depth, | 921 int save_at_depth, |
| 922 Label* miss) { | 922 Label* miss) { |
| 923 // Make sure there's no overlap between holder and object registers. | 923 // Make sure there's no overlap between holder and object registers. |
| 924 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 924 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 925 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 925 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 926 && !scratch2.is(scratch1)); | 926 && !scratch2.is(scratch1)); |
| 927 | 927 |
| 928 // Keep track of the current object in register reg. On the first | 928 // Keep track of the current object in register reg. On the first |
| 929 // iteration, reg is an alias for object_reg, on later iterations, | 929 // iteration, reg is an alias for object_reg, on later iterations, |
| 930 // it is an alias for holder_reg. | 930 // it is an alias for holder_reg. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 942 ++depth; | 942 ++depth; |
| 943 | 943 |
| 944 // Only global objects and objects that do not require access | 944 // Only global objects and objects that do not require access |
| 945 // checks are allowed in stubs. | 945 // checks are allowed in stubs. |
| 946 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 946 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
| 947 | 947 |
| 948 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 948 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
| 949 if (!current->HasFastProperties() && | 949 if (!current->HasFastProperties() && |
| 950 !current->IsJSGlobalObject() && | 950 !current->IsJSGlobalObject() && |
| 951 !current->IsJSGlobalProxy()) { | 951 !current->IsJSGlobalProxy()) { |
| 952 if (!name->IsInternalizedString()) { | 952 if (!name->IsUniqueName()) { |
| 953 name = factory()->InternalizeString(name); | 953 ASSERT(name->IsString()); |
| 954 name = factory()->InternalizeString(Handle<String>::cast(name)); |
| 954 } | 955 } |
| 955 ASSERT(current->property_dictionary()->FindEntry(*name) == | 956 ASSERT(current->property_dictionary()->FindEntry(*name) == |
| 956 StringDictionary::kNotFound); | 957 NameDictionary::kNotFound); |
| 957 | 958 |
| 958 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 959 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 959 scratch1, scratch2); | 960 scratch1, scratch2); |
| 960 | 961 |
| 961 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 962 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
| 962 reg = holder_reg; // From now on the object will be in holder_reg. | 963 reg = holder_reg; // From now on the object will be in holder_reg. |
| 963 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 964 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
| 964 } else { | 965 } else { |
| 965 bool in_new_space = heap()->InNewSpace(*prototype); | 966 bool in_new_space = heap()->InNewSpace(*prototype); |
| 966 Handle<Map> current_map(current->map()); | 967 Handle<Map> current_map(current->map()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 } | 1022 } |
| 1022 | 1023 |
| 1023 | 1024 |
| 1024 void StubCompiler::GenerateLoadField(Handle<JSObject> object, | 1025 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
| 1025 Handle<JSObject> holder, | 1026 Handle<JSObject> holder, |
| 1026 Register receiver, | 1027 Register receiver, |
| 1027 Register scratch1, | 1028 Register scratch1, |
| 1028 Register scratch2, | 1029 Register scratch2, |
| 1029 Register scratch3, | 1030 Register scratch3, |
| 1030 PropertyIndex index, | 1031 PropertyIndex index, |
| 1031 Handle<String> name, | 1032 Handle<Name> name, |
| 1032 Label* miss) { | 1033 Label* miss) { |
| 1033 // Check that the receiver isn't a smi. | 1034 // Check that the receiver isn't a smi. |
| 1034 __ JumpIfSmi(receiver, miss); | 1035 __ JumpIfSmi(receiver, miss); |
| 1035 | 1036 |
| 1036 // Check the prototype chain. | 1037 // Check the prototype chain. |
| 1037 Register reg = CheckPrototypes( | 1038 Register reg = CheckPrototypes( |
| 1038 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1039 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
| 1039 | 1040 |
| 1040 // Get the value from the properties. | 1041 // Get the value from the properties. |
| 1041 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); | 1042 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); |
| 1042 __ ret(0); | 1043 __ ret(0); |
| 1043 } | 1044 } |
| 1044 | 1045 |
| 1045 | 1046 |
| 1046 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, | 1047 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, |
| 1047 Register name_reg, | 1048 Register name_reg, |
| 1048 Register scratch1, | 1049 Register scratch1, |
| 1049 Register scratch2, | 1050 Register scratch2, |
| 1050 Register scratch3, | 1051 Register scratch3, |
| 1051 Handle<AccessorInfo> callback, | 1052 Handle<AccessorInfo> callback, |
| 1052 Handle<String> name, | 1053 Handle<Name> name, |
| 1053 Label* miss) { | 1054 Label* miss) { |
| 1054 ASSERT(!receiver.is(scratch1)); | 1055 ASSERT(!receiver.is(scratch1)); |
| 1055 ASSERT(!receiver.is(scratch2)); | 1056 ASSERT(!receiver.is(scratch2)); |
| 1056 ASSERT(!receiver.is(scratch3)); | 1057 ASSERT(!receiver.is(scratch3)); |
| 1057 | 1058 |
| 1058 // Load the properties dictionary. | 1059 // Load the properties dictionary. |
| 1059 Register dictionary = scratch1; | 1060 Register dictionary = scratch1; |
| 1060 __ movq(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 1061 __ movq(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
| 1061 | 1062 |
| 1062 // Probe the dictionary. | 1063 // Probe the dictionary. |
| 1063 Label probe_done; | 1064 Label probe_done; |
| 1064 StringDictionaryLookupStub::GeneratePositiveLookup(masm(), | 1065 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), |
| 1065 miss, | 1066 miss, |
| 1066 &probe_done, | 1067 &probe_done, |
| 1067 dictionary, | 1068 dictionary, |
| 1068 name_reg, | 1069 name_reg, |
| 1069 scratch2, | 1070 scratch2, |
| 1070 scratch3); | 1071 scratch3); |
| 1071 __ bind(&probe_done); | 1072 __ bind(&probe_done); |
| 1072 | 1073 |
| 1073 // If probing finds an entry in the dictionary, scratch3 contains the | 1074 // If probing finds an entry in the dictionary, scratch3 contains the |
| 1074 // index into the dictionary. Check that the value is the callback. | 1075 // index into the dictionary. Check that the value is the callback. |
| 1075 Register index = scratch3; | 1076 Register index = scratch3; |
| 1076 const int kElementsStartOffset = | 1077 const int kElementsStartOffset = |
| 1077 StringDictionary::kHeaderSize + | 1078 NameDictionary::kHeaderSize + |
| 1078 StringDictionary::kElementsStartIndex * kPointerSize; | 1079 NameDictionary::kElementsStartIndex * kPointerSize; |
| 1079 const int kValueOffset = kElementsStartOffset + kPointerSize; | 1080 const int kValueOffset = kElementsStartOffset + kPointerSize; |
| 1080 __ movq(scratch2, | 1081 __ movq(scratch2, |
| 1081 Operand(dictionary, index, times_pointer_size, | 1082 Operand(dictionary, index, times_pointer_size, |
| 1082 kValueOffset - kHeapObjectTag)); | 1083 kValueOffset - kHeapObjectTag)); |
| 1083 __ movq(scratch3, callback, RelocInfo::EMBEDDED_OBJECT); | 1084 __ movq(scratch3, callback, RelocInfo::EMBEDDED_OBJECT); |
| 1084 __ cmpq(scratch2, scratch3); | 1085 __ cmpq(scratch2, scratch3); |
| 1085 __ j(not_equal, miss); | 1086 __ j(not_equal, miss); |
| 1086 } | 1087 } |
| 1087 | 1088 |
| 1088 | 1089 |
| 1089 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, | 1090 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, |
| 1090 Handle<JSObject> holder, | 1091 Handle<JSObject> holder, |
| 1091 Register receiver, | 1092 Register receiver, |
| 1092 Register name_reg, | 1093 Register name_reg, |
| 1093 Register scratch1, | 1094 Register scratch1, |
| 1094 Register scratch2, | 1095 Register scratch2, |
| 1095 Register scratch3, | 1096 Register scratch3, |
| 1096 Register scratch4, | 1097 Register scratch4, |
| 1097 Handle<AccessorInfo> callback, | 1098 Handle<AccessorInfo> callback, |
| 1098 Handle<String> name, | 1099 Handle<Name> name, |
| 1099 Label* miss) { | 1100 Label* miss) { |
| 1100 // Check that the receiver isn't a smi. | 1101 // Check that the receiver isn't a smi. |
| 1101 __ JumpIfSmi(receiver, miss); | 1102 __ JumpIfSmi(receiver, miss); |
| 1102 | 1103 |
| 1103 // Check that the maps haven't changed. | 1104 // Check that the maps haven't changed. |
| 1104 Register reg = CheckPrototypes(object, receiver, holder, scratch1, | 1105 Register reg = CheckPrototypes(object, receiver, holder, scratch1, |
| 1105 scratch2, scratch3, name, miss); | 1106 scratch2, scratch3, name, miss); |
| 1106 | 1107 |
| 1107 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1108 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
| 1108 GenerateDictionaryLoadCallback( | 1109 GenerateDictionaryLoadCallback( |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 } | 1164 } |
| 1164 | 1165 |
| 1165 | 1166 |
| 1166 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, | 1167 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
| 1167 Handle<JSObject> holder, | 1168 Handle<JSObject> holder, |
| 1168 Register receiver, | 1169 Register receiver, |
| 1169 Register scratch1, | 1170 Register scratch1, |
| 1170 Register scratch2, | 1171 Register scratch2, |
| 1171 Register scratch3, | 1172 Register scratch3, |
| 1172 Handle<JSFunction> value, | 1173 Handle<JSFunction> value, |
| 1173 Handle<String> name, | 1174 Handle<Name> name, |
| 1174 Label* miss) { | 1175 Label* miss) { |
| 1175 // Check that the receiver isn't a smi. | 1176 // Check that the receiver isn't a smi. |
| 1176 __ JumpIfSmi(receiver, miss); | 1177 __ JumpIfSmi(receiver, miss); |
| 1177 | 1178 |
| 1178 // Check that the maps haven't changed. | 1179 // Check that the maps haven't changed. |
| 1179 CheckPrototypes( | 1180 CheckPrototypes( |
| 1180 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1181 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
| 1181 | 1182 |
| 1182 // Return the constant value. | 1183 // Return the constant value. |
| 1183 __ LoadHeapObject(rax, value); | 1184 __ LoadHeapObject(rax, value); |
| 1184 __ ret(0); | 1185 __ ret(0); |
| 1185 } | 1186 } |
| 1186 | 1187 |
| 1187 | 1188 |
| 1188 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, | 1189 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, |
| 1189 Handle<JSObject> interceptor_holder, | 1190 Handle<JSObject> interceptor_holder, |
| 1190 LookupResult* lookup, | 1191 LookupResult* lookup, |
| 1191 Register receiver, | 1192 Register receiver, |
| 1192 Register name_reg, | 1193 Register name_reg, |
| 1193 Register scratch1, | 1194 Register scratch1, |
| 1194 Register scratch2, | 1195 Register scratch2, |
| 1195 Register scratch3, | 1196 Register scratch3, |
| 1196 Handle<String> name, | 1197 Handle<Name> name, |
| 1197 Label* miss) { | 1198 Label* miss) { |
| 1198 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1199 ASSERT(interceptor_holder->HasNamedInterceptor()); |
| 1199 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 1200 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
| 1200 | 1201 |
| 1201 // Check that the receiver isn't a smi. | 1202 // Check that the receiver isn't a smi. |
| 1202 __ JumpIfSmi(receiver, miss); | 1203 __ JumpIfSmi(receiver, miss); |
| 1203 | 1204 |
| 1204 // So far the most popular follow ups for interceptor loads are FIELD | 1205 // So far the most popular follow ups for interceptor loads are FIELD |
| 1205 // and CALLBACKS, so inline only them, other cases may be added | 1206 // and CALLBACKS, so inline only them, other cases may be added |
| 1206 // later. | 1207 // later. |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1328 name_reg, interceptor_holder); | 1329 name_reg, interceptor_holder); |
| 1329 __ push(scratch2); // restore old return address | 1330 __ push(scratch2); // restore old return address |
| 1330 | 1331 |
| 1331 ExternalReference ref = ExternalReference( | 1332 ExternalReference ref = ExternalReference( |
| 1332 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); | 1333 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); |
| 1333 __ TailCallExternalReference(ref, 6, 1); | 1334 __ TailCallExternalReference(ref, 6, 1); |
| 1334 } | 1335 } |
| 1335 } | 1336 } |
| 1336 | 1337 |
| 1337 | 1338 |
| 1338 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 1339 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
| 1339 if (kind_ == Code::KEYED_CALL_IC) { | 1340 if (kind_ == Code::KEYED_CALL_IC) { |
| 1340 __ Cmp(rcx, name); | 1341 __ Cmp(rcx, name); |
| 1341 __ j(not_equal, miss); | 1342 __ j(not_equal, miss); |
| 1342 } | 1343 } |
| 1343 } | 1344 } |
| 1344 | 1345 |
| 1345 | 1346 |
| 1346 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, | 1347 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, |
| 1347 Handle<JSObject> holder, | 1348 Handle<JSObject> holder, |
| 1348 Handle<String> name, | 1349 Handle<Name> name, |
| 1349 Label* miss) { | 1350 Label* miss) { |
| 1350 ASSERT(holder->IsGlobalObject()); | 1351 ASSERT(holder->IsGlobalObject()); |
| 1351 | 1352 |
| 1352 // Get the number of arguments. | 1353 // Get the number of arguments. |
| 1353 const int argc = arguments().immediate(); | 1354 const int argc = arguments().immediate(); |
| 1354 | 1355 |
| 1355 // Get the receiver from the stack. | 1356 // Get the receiver from the stack. |
| 1356 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1357 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
| 1357 | 1358 |
| 1358 | 1359 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1397 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
| 1397 kind_, | 1398 kind_, |
| 1398 extra_state_); | 1399 extra_state_); |
| 1399 __ Jump(code, RelocInfo::CODE_TARGET); | 1400 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1400 } | 1401 } |
| 1401 | 1402 |
| 1402 | 1403 |
| 1403 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1404 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
| 1404 Handle<JSObject> holder, | 1405 Handle<JSObject> holder, |
| 1405 PropertyIndex index, | 1406 PropertyIndex index, |
| 1406 Handle<String> name) { | 1407 Handle<Name> name) { |
| 1407 // ----------- S t a t e ------------- | 1408 // ----------- S t a t e ------------- |
| 1408 // rcx : function name | 1409 // rcx : function name |
| 1409 // rsp[0] : return address | 1410 // rsp[0] : return address |
| 1410 // rsp[8] : argument argc | 1411 // rsp[8] : argument argc |
| 1411 // rsp[16] : argument argc - 1 | 1412 // rsp[16] : argument argc - 1 |
| 1412 // ... | 1413 // ... |
| 1413 // rsp[argc * 8] : argument 1 | 1414 // rsp[argc * 8] : argument 1 |
| 1414 // rsp[(argc + 1) * 8] : argument 0 = receiver | 1415 // rsp[(argc + 1) * 8] : argument 0 = receiver |
| 1415 // ----------------------------------- | 1416 // ----------------------------------- |
| 1416 Label miss; | 1417 Label miss; |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2184 GenerateMissBranch(); | 2185 GenerateMissBranch(); |
| 2185 | 2186 |
| 2186 // Return the generated code. | 2187 // Return the generated code. |
| 2187 return GetCode(function); | 2188 return GetCode(function); |
| 2188 } | 2189 } |
| 2189 | 2190 |
| 2190 | 2191 |
| 2191 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, | 2192 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, |
| 2192 Handle<JSObject> holder, | 2193 Handle<JSObject> holder, |
| 2193 Handle<JSFunction> function, | 2194 Handle<JSFunction> function, |
| 2194 Handle<String> name, | 2195 Handle<Name> name, |
| 2195 CheckType check) { | 2196 CheckType check) { |
| 2196 // ----------- S t a t e ------------- | 2197 // ----------- S t a t e ------------- |
| 2197 // rcx : function name | 2198 // rcx : function name |
| 2198 // rsp[0] : return address | 2199 // rsp[0] : return address |
| 2199 // rsp[8] : argument argc | 2200 // rsp[8] : argument argc |
| 2200 // rsp[16] : argument argc - 1 | 2201 // rsp[16] : argument argc - 1 |
| 2201 // ... | 2202 // ... |
| 2202 // rsp[argc * 8] : argument 1 | 2203 // rsp[argc * 8] : argument 1 |
| 2203 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2204 // rsp[(argc + 1) * 8] : argument 0 = receiver |
| 2204 // ----------------------------------- | 2205 // ----------------------------------- |
| 2205 | 2206 |
| 2206 if (HasCustomCallGenerator(function)) { | 2207 if (HasCustomCallGenerator(function)) { |
| 2207 Handle<Code> code = CompileCustomCall(object, holder, | 2208 Handle<Code> code = CompileCustomCall(object, holder, |
| 2208 Handle<JSGlobalPropertyCell>::null(), | 2209 Handle<JSGlobalPropertyCell>::null(), |
| 2209 function, name); | 2210 function, Handle<String>::cast(name)); |
| 2210 // A null handle means bail out to the regular compiler code below. | 2211 // A null handle means bail out to the regular compiler code below. |
| 2211 if (!code.is_null()) return code; | 2212 if (!code.is_null()) return code; |
| 2212 } | 2213 } |
| 2213 | 2214 |
| 2214 Label miss; | 2215 Label miss; |
| 2215 GenerateNameCheck(name, &miss); | 2216 GenerateNameCheck(name, &miss); |
| 2216 | 2217 |
| 2217 // Get the receiver from the stack. | 2218 // Get the receiver from the stack. |
| 2218 const int argc = arguments().immediate(); | 2219 const int argc = arguments().immediate(); |
| 2219 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2220 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2322 __ bind(&miss); | 2323 __ bind(&miss); |
| 2323 GenerateMissBranch(); | 2324 GenerateMissBranch(); |
| 2324 | 2325 |
| 2325 // Return the generated code. | 2326 // Return the generated code. |
| 2326 return GetCode(function); | 2327 return GetCode(function); |
| 2327 } | 2328 } |
| 2328 | 2329 |
| 2329 | 2330 |
| 2330 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2331 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
| 2331 Handle<JSObject> holder, | 2332 Handle<JSObject> holder, |
| 2332 Handle<String> name) { | 2333 Handle<Name> name) { |
| 2333 // ----------- S t a t e ------------- | 2334 // ----------- S t a t e ------------- |
| 2334 // rcx : function name | 2335 // rcx : function name |
| 2335 // rsp[0] : return address | 2336 // rsp[0] : return address |
| 2336 // rsp[8] : argument argc | 2337 // rsp[8] : argument argc |
| 2337 // rsp[16] : argument argc - 1 | 2338 // rsp[16] : argument argc - 1 |
| 2338 // ... | 2339 // ... |
| 2339 // rsp[argc * 8] : argument 1 | 2340 // rsp[argc * 8] : argument 1 |
| 2340 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2341 // rsp[(argc + 1) * 8] : argument 0 = receiver |
| 2341 // ----------------------------------- | 2342 // ----------------------------------- |
| 2342 Label miss; | 2343 Label miss; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2385 // Return the generated code. | 2386 // Return the generated code. |
| 2386 return GetCode(Code::INTERCEPTOR, name); | 2387 return GetCode(Code::INTERCEPTOR, name); |
| 2387 } | 2388 } |
| 2388 | 2389 |
| 2389 | 2390 |
| 2390 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2391 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2391 Handle<JSObject> object, | 2392 Handle<JSObject> object, |
| 2392 Handle<GlobalObject> holder, | 2393 Handle<GlobalObject> holder, |
| 2393 Handle<JSGlobalPropertyCell> cell, | 2394 Handle<JSGlobalPropertyCell> cell, |
| 2394 Handle<JSFunction> function, | 2395 Handle<JSFunction> function, |
| 2395 Handle<String> name) { | 2396 Handle<Name> name) { |
| 2396 // ----------- S t a t e ------------- | 2397 // ----------- S t a t e ------------- |
| 2397 // rcx : function name | 2398 // rcx : function name |
| 2398 // rsp[0] : return address | 2399 // rsp[0] : return address |
| 2399 // rsp[8] : argument argc | 2400 // rsp[8] : argument argc |
| 2400 // rsp[16] : argument argc - 1 | 2401 // rsp[16] : argument argc - 1 |
| 2401 // ... | 2402 // ... |
| 2402 // rsp[argc * 8] : argument 1 | 2403 // rsp[argc * 8] : argument 1 |
| 2403 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2404 // rsp[(argc + 1) * 8] : argument 0 = receiver |
| 2404 // ----------------------------------- | 2405 // ----------------------------------- |
| 2405 | 2406 |
| 2406 if (HasCustomCallGenerator(function)) { | 2407 if (HasCustomCallGenerator(function)) { |
| 2407 Handle<Code> code = CompileCustomCall(object, holder, cell, function, name); | 2408 Handle<Code> code = CompileCustomCall( |
| 2409 object, holder, cell, function, Handle<String>::cast(name)); |
| 2408 // A null handle means bail out to the regular compiler code below. | 2410 // A null handle means bail out to the regular compiler code below. |
| 2409 if (!code.is_null()) return code; | 2411 if (!code.is_null()) return code; |
| 2410 } | 2412 } |
| 2411 | 2413 |
| 2412 Label miss; | 2414 Label miss; |
| 2413 GenerateNameCheck(name, &miss); | 2415 GenerateNameCheck(name, &miss); |
| 2414 | 2416 |
| 2415 // Get the number of arguments. | 2417 // Get the number of arguments. |
| 2416 const int argc = arguments().immediate(); | 2418 const int argc = arguments().immediate(); |
| 2417 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2419 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2446 GenerateMissBranch(); | 2448 GenerateMissBranch(); |
| 2447 | 2449 |
| 2448 // Return the generated code. | 2450 // Return the generated code. |
| 2449 return GetCode(Code::NORMAL, name); | 2451 return GetCode(Code::NORMAL, name); |
| 2450 } | 2452 } |
| 2451 | 2453 |
| 2452 | 2454 |
| 2453 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2455 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
| 2454 int index, | 2456 int index, |
| 2455 Handle<Map> transition, | 2457 Handle<Map> transition, |
| 2456 Handle<String> name) { | 2458 Handle<Name> name) { |
| 2457 // ----------- S t a t e ------------- | 2459 // ----------- S t a t e ------------- |
| 2458 // -- rax : value | 2460 // -- rax : value |
| 2459 // -- rcx : name | 2461 // -- rcx : name |
| 2460 // -- rdx : receiver | 2462 // -- rdx : receiver |
| 2461 // -- rsp[0] : return address | 2463 // -- rsp[0] : return address |
| 2462 // ----------------------------------- | 2464 // ----------------------------------- |
| 2463 Label miss; | 2465 Label miss; |
| 2464 | 2466 |
| 2465 // Generate store field code. Preserves receiver and name on jump to miss. | 2467 // Generate store field code. Preserves receiver and name on jump to miss. |
| 2466 GenerateStoreField(masm(), | 2468 GenerateStoreField(masm(), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2477 __ Jump(ic, RelocInfo::CODE_TARGET); | 2479 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2478 | 2480 |
| 2479 // Return the generated code. | 2481 // Return the generated code. |
| 2480 return GetCode(transition.is_null() | 2482 return GetCode(transition.is_null() |
| 2481 ? Code::FIELD | 2483 ? Code::FIELD |
| 2482 : Code::MAP_TRANSITION, name); | 2484 : Code::MAP_TRANSITION, name); |
| 2483 } | 2485 } |
| 2484 | 2486 |
| 2485 | 2487 |
| 2486 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2488 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2487 Handle<String> name, | 2489 Handle<Name> name, |
| 2488 Handle<JSObject> receiver, | 2490 Handle<JSObject> receiver, |
| 2489 Handle<JSObject> holder, | 2491 Handle<JSObject> holder, |
| 2490 Handle<AccessorInfo> callback) { | 2492 Handle<AccessorInfo> callback) { |
| 2491 // ----------- S t a t e ------------- | 2493 // ----------- S t a t e ------------- |
| 2492 // -- rax : value | 2494 // -- rax : value |
| 2493 // -- rcx : name | 2495 // -- rcx : name |
| 2494 // -- rdx : receiver | 2496 // -- rdx : receiver |
| 2495 // -- rsp[0] : return address | 2497 // -- rsp[0] : return address |
| 2496 // ----------------------------------- | 2498 // ----------------------------------- |
| 2497 Label miss; | 2499 Label miss; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2564 } | 2566 } |
| 2565 __ ret(0); | 2567 __ ret(0); |
| 2566 } | 2568 } |
| 2567 | 2569 |
| 2568 | 2570 |
| 2569 #undef __ | 2571 #undef __ |
| 2570 #define __ ACCESS_MASM(masm()) | 2572 #define __ ACCESS_MASM(masm()) |
| 2571 | 2573 |
| 2572 | 2574 |
| 2573 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 2575 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
| 2574 Handle<String> name, | 2576 Handle<Name> name, |
| 2575 Handle<JSObject> receiver, | 2577 Handle<JSObject> receiver, |
| 2576 Handle<JSObject> holder, | 2578 Handle<JSObject> holder, |
| 2577 Handle<JSFunction> setter) { | 2579 Handle<JSFunction> setter) { |
| 2578 // ----------- S t a t e ------------- | 2580 // ----------- S t a t e ------------- |
| 2579 // -- rax : value | 2581 // -- rax : value |
| 2580 // -- rcx : name | 2582 // -- rcx : name |
| 2581 // -- rdx : receiver | 2583 // -- rdx : receiver |
| 2582 // -- rsp[0] : return address | 2584 // -- rsp[0] : return address |
| 2583 // ----------------------------------- | 2585 // ----------------------------------- |
| 2584 Label miss; | 2586 Label miss; |
| 2585 | 2587 |
| 2586 // Check that the maps haven't changed. | 2588 // Check that the maps haven't changed. |
| 2587 __ JumpIfSmi(rdx, &miss); | 2589 __ JumpIfSmi(rdx, &miss); |
| 2588 CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss); | 2590 CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss); |
| 2589 | 2591 |
| 2590 GenerateStoreViaSetter(masm(), setter); | 2592 GenerateStoreViaSetter(masm(), setter); |
| 2591 | 2593 |
| 2592 __ bind(&miss); | 2594 __ bind(&miss); |
| 2593 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2595 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
| 2594 __ Jump(ic, RelocInfo::CODE_TARGET); | 2596 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2595 | 2597 |
| 2596 // Return the generated code. | 2598 // Return the generated code. |
| 2597 return GetCode(Code::CALLBACKS, name); | 2599 return GetCode(Code::CALLBACKS, name); |
| 2598 } | 2600 } |
| 2599 | 2601 |
| 2600 | 2602 |
| 2601 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2603 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
| 2602 Handle<JSObject> receiver, | 2604 Handle<JSObject> receiver, |
| 2603 Handle<String> name) { | 2605 Handle<Name> name) { |
| 2604 // ----------- S t a t e ------------- | 2606 // ----------- S t a t e ------------- |
| 2605 // -- rax : value | 2607 // -- rax : value |
| 2606 // -- rcx : name | 2608 // -- rcx : name |
| 2607 // -- rdx : receiver | 2609 // -- rdx : receiver |
| 2608 // -- rsp[0] : return address | 2610 // -- rsp[0] : return address |
| 2609 // ----------------------------------- | 2611 // ----------------------------------- |
| 2610 Label miss; | 2612 Label miss; |
| 2611 | 2613 |
| 2612 // Check that the map of the object hasn't changed. | 2614 // Check that the map of the object hasn't changed. |
| 2613 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, | 2615 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2640 __ Jump(ic, RelocInfo::CODE_TARGET); | 2642 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2641 | 2643 |
| 2642 // Return the generated code. | 2644 // Return the generated code. |
| 2643 return GetCode(Code::INTERCEPTOR, name); | 2645 return GetCode(Code::INTERCEPTOR, name); |
| 2644 } | 2646 } |
| 2645 | 2647 |
| 2646 | 2648 |
| 2647 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2649 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
| 2648 Handle<GlobalObject> object, | 2650 Handle<GlobalObject> object, |
| 2649 Handle<JSGlobalPropertyCell> cell, | 2651 Handle<JSGlobalPropertyCell> cell, |
| 2650 Handle<String> name) { | 2652 Handle<Name> name) { |
| 2651 // ----------- S t a t e ------------- | 2653 // ----------- S t a t e ------------- |
| 2652 // -- rax : value | 2654 // -- rax : value |
| 2653 // -- rcx : name | 2655 // -- rcx : name |
| 2654 // -- rdx : receiver | 2656 // -- rdx : receiver |
| 2655 // -- rsp[0] : return address | 2657 // -- rsp[0] : return address |
| 2656 // ----------------------------------- | 2658 // ----------------------------------- |
| 2657 Label miss; | 2659 Label miss; |
| 2658 | 2660 |
| 2659 // Check that the map of the global has not changed. | 2661 // Check that the map of the global has not changed. |
| 2660 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 2662 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2688 __ Jump(ic, RelocInfo::CODE_TARGET); | 2690 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2689 | 2691 |
| 2690 // Return the generated code. | 2692 // Return the generated code. |
| 2691 return GetCode(Code::NORMAL, name); | 2693 return GetCode(Code::NORMAL, name); |
| 2692 } | 2694 } |
| 2693 | 2695 |
| 2694 | 2696 |
| 2695 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2697 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
| 2696 int index, | 2698 int index, |
| 2697 Handle<Map> transition, | 2699 Handle<Map> transition, |
| 2698 Handle<String> name) { | 2700 Handle<Name> name) { |
| 2699 // ----------- S t a t e ------------- | 2701 // ----------- S t a t e ------------- |
| 2700 // -- rax : value | 2702 // -- rax : value |
| 2701 // -- rcx : key | 2703 // -- rcx : key |
| 2702 // -- rdx : receiver | 2704 // -- rdx : receiver |
| 2703 // -- rsp[0] : return address | 2705 // -- rsp[0] : return address |
| 2704 // ----------------------------------- | 2706 // ----------------------------------- |
| 2705 Label miss; | 2707 Label miss; |
| 2706 | 2708 |
| 2707 Counters* counters = isolate()->counters(); | 2709 Counters* counters = isolate()->counters(); |
| 2708 __ IncrementCounter(counters->keyed_store_field(), 1); | 2710 __ IncrementCounter(counters->keyed_store_field(), 1); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2791 __ jmp(ic, RelocInfo::CODE_TARGET); | 2793 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2792 | 2794 |
| 2793 // Return the generated code. | 2795 // Return the generated code. |
| 2794 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 2796 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
| 2795 } | 2797 } |
| 2796 | 2798 |
| 2797 | 2799 |
| 2798 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2800 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
| 2799 Handle<JSObject> object, | 2801 Handle<JSObject> object, |
| 2800 Handle<JSObject> last, | 2802 Handle<JSObject> last, |
| 2801 Handle<String> name, | 2803 Handle<Name> name, |
| 2802 Handle<GlobalObject> global) { | 2804 Handle<GlobalObject> global) { |
| 2803 // ----------- S t a t e ------------- | 2805 // ----------- S t a t e ------------- |
| 2804 // -- rax : receiver | 2806 // -- rax : receiver |
| 2805 // -- rcx : name | 2807 // -- rcx : name |
| 2806 // -- rsp[0] : return address | 2808 // -- rsp[0] : return address |
| 2807 // ----------------------------------- | 2809 // ----------------------------------- |
| 2808 Label miss; | 2810 Label miss; |
| 2809 | 2811 |
| 2810 // Check that receiver is not a smi. | 2812 // Check that receiver is not a smi. |
| 2811 __ JumpIfSmi(rax, &miss); | 2813 __ JumpIfSmi(rax, &miss); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2850 } | 2852 } |
| 2851 | 2853 |
| 2852 | 2854 |
| 2853 Register* KeyedLoadStubCompiler::registers() { | 2855 Register* KeyedLoadStubCompiler::registers() { |
| 2854 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 2856 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
| 2855 static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 }; | 2857 static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 }; |
| 2856 return registers; | 2858 return registers; |
| 2857 } | 2859 } |
| 2858 | 2860 |
| 2859 | 2861 |
| 2860 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name, | 2862 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, |
| 2861 Register name_reg, | 2863 Register name_reg, |
| 2862 Label* miss) { | 2864 Label* miss) { |
| 2863 __ Cmp(name_reg, name); | 2865 __ Cmp(name_reg, name); |
| 2864 __ j(not_equal, miss); | 2866 __ j(not_equal, miss); |
| 2865 } | 2867 } |
| 2866 | 2868 |
| 2867 | 2869 |
| 2868 #undef __ | 2870 #undef __ |
| 2869 #define __ ACCESS_MASM(masm) | 2871 #define __ ACCESS_MASM(masm) |
| 2870 | 2872 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2898 } | 2900 } |
| 2899 | 2901 |
| 2900 | 2902 |
| 2901 #undef __ | 2903 #undef __ |
| 2902 #define __ ACCESS_MASM(masm()) | 2904 #define __ ACCESS_MASM(masm()) |
| 2903 | 2905 |
| 2904 | 2906 |
| 2905 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 2907 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
| 2906 Handle<JSObject> receiver, | 2908 Handle<JSObject> receiver, |
| 2907 Handle<JSObject> holder, | 2909 Handle<JSObject> holder, |
| 2908 Handle<String> name, | 2910 Handle<Name> name, |
| 2909 Handle<JSFunction> getter) { | 2911 Handle<JSFunction> getter) { |
| 2910 // ----------- S t a t e ------------- | 2912 // ----------- S t a t e ------------- |
| 2911 // -- rax : receiver | 2913 // -- rax : receiver |
| 2912 // -- rcx : name | 2914 // -- rcx : name |
| 2913 // -- rsp[0] : return address | 2915 // -- rsp[0] : return address |
| 2914 // ----------------------------------- | 2916 // ----------------------------------- |
| 2915 Label miss; | 2917 Label miss; |
| 2916 | 2918 |
| 2917 // Check that the maps haven't changed. | 2919 // Check that the maps haven't changed. |
| 2918 __ JumpIfSmi(rax, &miss); | 2920 __ JumpIfSmi(rax, &miss); |
| 2919 CheckPrototypes(receiver, rax, holder, rbx, rdx, rdi, name, &miss); | 2921 CheckPrototypes(receiver, rax, holder, rbx, rdx, rdi, name, &miss); |
| 2920 | 2922 |
| 2921 GenerateLoadViaGetter(masm(), getter), | 2923 GenerateLoadViaGetter(masm(), getter), |
| 2922 | 2924 |
| 2923 __ bind(&miss); | 2925 __ bind(&miss); |
| 2924 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2926 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 2925 | 2927 |
| 2926 // Return the generated code. | 2928 // Return the generated code. |
| 2927 return GetCode(Code::CALLBACKS, name); | 2929 return GetCode(Code::CALLBACKS, name); |
| 2928 } | 2930 } |
| 2929 | 2931 |
| 2930 | 2932 |
| 2931 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 2933 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 2932 Handle<JSObject> object, | 2934 Handle<JSObject> object, |
| 2933 Handle<GlobalObject> holder, | 2935 Handle<GlobalObject> holder, |
| 2934 Handle<JSGlobalPropertyCell> cell, | 2936 Handle<JSGlobalPropertyCell> cell, |
| 2935 Handle<String> name, | 2937 Handle<Name> name, |
| 2936 bool is_dont_delete) { | 2938 bool is_dont_delete) { |
| 2937 // ----------- S t a t e ------------- | 2939 // ----------- S t a t e ------------- |
| 2938 // -- rax : receiver | 2940 // -- rax : receiver |
| 2939 // -- rcx : name | 2941 // -- rcx : name |
| 2940 // -- rsp[0] : return address | 2942 // -- rsp[0] : return address |
| 2941 // ----------------------------------- | 2943 // ----------------------------------- |
| 2942 Label miss; | 2944 Label miss; |
| 2943 | 2945 |
| 2944 // Check that the maps haven't changed. | 2946 // Check that the maps haven't changed. |
| 2945 __ JumpIfSmi(rax, &miss); | 2947 __ JumpIfSmi(rax, &miss); |
| (...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3698 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3700 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
| 3699 } | 3701 } |
| 3700 } | 3702 } |
| 3701 | 3703 |
| 3702 | 3704 |
| 3703 #undef __ | 3705 #undef __ |
| 3704 | 3706 |
| 3705 } } // namespace v8::internal | 3707 } } // namespace v8::internal |
| 3706 | 3708 |
| 3707 #endif // V8_TARGET_ARCH_X64 | 3709 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |