| 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 123 |
| 124 // Miss: fall through. | 124 // Miss: fall through. |
| 125 __ bind(&miss); | 125 __ bind(&miss); |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 // Helper function used to check that the dictionary doesn't contain | 129 // Helper function used to check that the dictionary doesn't contain |
| 130 // the property. This function may return false negatives, so miss_label | 130 // the property. This function may return false negatives, so miss_label |
| 131 // must always call a backup property check that is complete. | 131 // must always call a backup property check that is complete. |
| 132 // This function is safe to call if the receiver has fast properties. | 132 // This function is safe to call if the receiver has fast properties. |
| 133 // Name must be internalized and receiver must be a heap object. | 133 // Name must be unique and receiver must be a heap object. |
| 134 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 134 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
| 135 Label* miss_label, | 135 Label* miss_label, |
| 136 Register receiver, | 136 Register receiver, |
| 137 Handle<String> name, | 137 Handle<Name> name, |
| 138 Register scratch0, | 138 Register scratch0, |
| 139 Register scratch1) { | 139 Register scratch1) { |
| 140 ASSERT(name->IsInternalizedString()); | 140 ASSERT(name->IsUniqueName()); |
| 141 Counters* counters = masm->isolate()->counters(); | 141 Counters* counters = masm->isolate()->counters(); |
| 142 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 142 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
| 143 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 143 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
| 144 | 144 |
| 145 Label done; | 145 Label done; |
| 146 | 146 |
| 147 const int kInterceptorOrAccessCheckNeededMask = | 147 const int kInterceptorOrAccessCheckNeededMask = |
| 148 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 148 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
| 149 | 149 |
| 150 // Bail out if the receiver has a named interceptor or requires access checks. | 150 // Bail out if the receiver has a named interceptor or requires access checks. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 166 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 166 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
| 167 Register tmp = properties; | 167 Register tmp = properties; |
| 168 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 168 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
| 169 __ cmp(map, tmp); | 169 __ cmp(map, tmp); |
| 170 __ b(ne, miss_label); | 170 __ b(ne, miss_label); |
| 171 | 171 |
| 172 // Restore the temporarily used register. | 172 // Restore the temporarily used register. |
| 173 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 173 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 174 | 174 |
| 175 | 175 |
| 176 StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 176 NameDictionaryLookupStub::GenerateNegativeLookup(masm, |
| 177 miss_label, | 177 miss_label, |
| 178 &done, | 178 &done, |
| 179 receiver, | 179 receiver, |
| 180 properties, | 180 properties, |
| 181 name, | 181 name, |
| 182 scratch1); | 182 scratch1); |
| 183 __ bind(&done); | 183 __ bind(&done); |
| 184 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 184 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
| 185 } | 185 } |
| 186 | 186 |
| 187 | 187 |
| 188 void StubCache::GenerateProbe(MacroAssembler* masm, | 188 void StubCache::GenerateProbe(MacroAssembler* masm, |
| 189 Code::Flags flags, | 189 Code::Flags flags, |
| 190 Register receiver, | 190 Register receiver, |
| 191 Register name, | 191 Register name, |
| 192 Register scratch, | 192 Register scratch, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 221 ASSERT(!extra3.is(no_reg)); | 221 ASSERT(!extra3.is(no_reg)); |
| 222 | 222 |
| 223 Counters* counters = masm->isolate()->counters(); | 223 Counters* counters = masm->isolate()->counters(); |
| 224 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, | 224 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, |
| 225 extra2, extra3); | 225 extra2, extra3); |
| 226 | 226 |
| 227 // Check that the receiver isn't a smi. | 227 // Check that the receiver isn't a smi. |
| 228 __ JumpIfSmi(receiver, &miss); | 228 __ JumpIfSmi(receiver, &miss); |
| 229 | 229 |
| 230 // Get the map of the receiver and compute the hash. | 230 // Get the map of the receiver and compute the hash. |
| 231 __ ldr(scratch, FieldMemOperand(name, String::kHashFieldOffset)); | 231 __ ldr(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); |
| 232 __ ldr(ip, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 232 __ ldr(ip, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 233 __ add(scratch, scratch, Operand(ip)); | 233 __ add(scratch, scratch, Operand(ip)); |
| 234 uint32_t mask = kPrimaryTableSize - 1; | 234 uint32_t mask = kPrimaryTableSize - 1; |
| 235 // We shift out the last two bits because they are not part of the hash and | 235 // We shift out the last two bits because they are not part of the hash and |
| 236 // they are always 01 for maps. | 236 // they are always 01 for maps. |
| 237 __ mov(scratch, Operand(scratch, LSR, kHeapObjectTagSize)); | 237 __ mov(scratch, Operand(scratch, LSR, kHeapObjectTagSize)); |
| 238 // Mask down the eor argument to the minimum to keep the immediate | 238 // Mask down the eor argument to the minimum to keep the immediate |
| 239 // ARM-encodable. | 239 // ARM-encodable. |
| 240 __ eor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); | 240 __ eor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); |
| 241 // Prefer and_ to ubfx here because ubfx takes 2 cycles. | 241 // Prefer and_ to ubfx here because ubfx takes 2 cycles. |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 | 435 |
| 436 | 436 |
| 437 // Generate StoreField code, value is passed in r0 register. | 437 // Generate StoreField code, value is passed in r0 register. |
| 438 // When leaving generated code after success, the receiver_reg and name_reg | 438 // When leaving generated code after success, the receiver_reg and name_reg |
| 439 // may be clobbered. Upon branch to miss_label, the receiver and name | 439 // may be clobbered. Upon branch to miss_label, the receiver and name |
| 440 // registers have their original values. | 440 // registers have their original values. |
| 441 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 441 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| 442 Handle<JSObject> object, | 442 Handle<JSObject> object, |
| 443 int index, | 443 int index, |
| 444 Handle<Map> transition, | 444 Handle<Map> transition, |
| 445 Handle<String> name, | 445 Handle<Name> name, |
| 446 Register receiver_reg, | 446 Register receiver_reg, |
| 447 Register name_reg, | 447 Register name_reg, |
| 448 Register scratch1, | 448 Register scratch1, |
| 449 Register scratch2, | 449 Register scratch2, |
| 450 Label* miss_label) { | 450 Label* miss_label) { |
| 451 // r0 : value | 451 // r0 : value |
| 452 Label exit; | 452 Label exit; |
| 453 | 453 |
| 454 LookupResult lookup(masm->isolate()); | 454 LookupResult lookup(masm->isolate()); |
| 455 object->Lookup(*name, &lookup); | 455 object->Lookup(*name, &lookup); |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 Register name, | 766 Register name, |
| 767 Code::ExtraICState extra_ic_state) | 767 Code::ExtraICState extra_ic_state) |
| 768 : stub_compiler_(stub_compiler), | 768 : stub_compiler_(stub_compiler), |
| 769 arguments_(arguments), | 769 arguments_(arguments), |
| 770 name_(name), | 770 name_(name), |
| 771 extra_ic_state_(extra_ic_state) {} | 771 extra_ic_state_(extra_ic_state) {} |
| 772 | 772 |
| 773 void Compile(MacroAssembler* masm, | 773 void Compile(MacroAssembler* masm, |
| 774 Handle<JSObject> object, | 774 Handle<JSObject> object, |
| 775 Handle<JSObject> holder, | 775 Handle<JSObject> holder, |
| 776 Handle<String> name, | 776 Handle<Name> name, |
| 777 LookupResult* lookup, | 777 LookupResult* lookup, |
| 778 Register receiver, | 778 Register receiver, |
| 779 Register scratch1, | 779 Register scratch1, |
| 780 Register scratch2, | 780 Register scratch2, |
| 781 Register scratch3, | 781 Register scratch3, |
| 782 Label* miss) { | 782 Label* miss) { |
| 783 ASSERT(holder->HasNamedInterceptor()); | 783 ASSERT(holder->HasNamedInterceptor()); |
| 784 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 784 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
| 785 | 785 |
| 786 // Check that the receiver isn't a smi. | 786 // Check that the receiver isn't a smi. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 797 | 797 |
| 798 private: | 798 private: |
| 799 void CompileCacheable(MacroAssembler* masm, | 799 void CompileCacheable(MacroAssembler* masm, |
| 800 Handle<JSObject> object, | 800 Handle<JSObject> object, |
| 801 Register receiver, | 801 Register receiver, |
| 802 Register scratch1, | 802 Register scratch1, |
| 803 Register scratch2, | 803 Register scratch2, |
| 804 Register scratch3, | 804 Register scratch3, |
| 805 Handle<JSObject> interceptor_holder, | 805 Handle<JSObject> interceptor_holder, |
| 806 LookupResult* lookup, | 806 LookupResult* lookup, |
| 807 Handle<String> name, | 807 Handle<Name> name, |
| 808 const CallOptimization& optimization, | 808 const CallOptimization& optimization, |
| 809 Label* miss_label) { | 809 Label* miss_label) { |
| 810 ASSERT(optimization.is_constant_call()); | 810 ASSERT(optimization.is_constant_call()); |
| 811 ASSERT(!lookup->holder()->IsGlobalObject()); | 811 ASSERT(!lookup->holder()->IsGlobalObject()); |
| 812 Counters* counters = masm->isolate()->counters(); | 812 Counters* counters = masm->isolate()->counters(); |
| 813 int depth1 = kInvalidProtoDepth; | 813 int depth1 = kInvalidProtoDepth; |
| 814 int depth2 = kInvalidProtoDepth; | 814 int depth2 = kInvalidProtoDepth; |
| 815 bool can_do_fast_api_call = false; | 815 bool can_do_fast_api_call = false; |
| 816 if (optimization.is_simple_api_call() && | 816 if (optimization.is_simple_api_call() && |
| 817 !lookup->holder()->IsGlobalObject()) { | 817 !lookup->holder()->IsGlobalObject()) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 FreeSpaceForFastApiCall(masm); | 891 FreeSpaceForFastApiCall(masm); |
| 892 } | 892 } |
| 893 } | 893 } |
| 894 | 894 |
| 895 void CompileRegular(MacroAssembler* masm, | 895 void CompileRegular(MacroAssembler* masm, |
| 896 Handle<JSObject> object, | 896 Handle<JSObject> object, |
| 897 Register receiver, | 897 Register receiver, |
| 898 Register scratch1, | 898 Register scratch1, |
| 899 Register scratch2, | 899 Register scratch2, |
| 900 Register scratch3, | 900 Register scratch3, |
| 901 Handle<String> name, | 901 Handle<Name> name, |
| 902 Handle<JSObject> interceptor_holder, | 902 Handle<JSObject> interceptor_holder, |
| 903 Label* miss_label) { | 903 Label* miss_label) { |
| 904 Register holder = | 904 Register holder = |
| 905 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 905 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, |
| 906 scratch1, scratch2, scratch3, | 906 scratch1, scratch2, scratch3, |
| 907 name, miss_label); | 907 name, miss_label); |
| 908 | 908 |
| 909 // Call a runtime function to load the interceptor property. | 909 // Call a runtime function to load the interceptor property. |
| 910 FrameScope scope(masm, StackFrame::INTERNAL); | 910 FrameScope scope(masm, StackFrame::INTERNAL); |
| 911 // Save the name_ register across the call. | 911 // Save the name_ register across the call. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 Register name_; | 948 Register name_; |
| 949 Code::ExtraICState extra_ic_state_; | 949 Code::ExtraICState extra_ic_state_; |
| 950 }; | 950 }; |
| 951 | 951 |
| 952 | 952 |
| 953 // Generate code to check that a global property cell is empty. Create | 953 // Generate code to check that a global property cell is empty. Create |
| 954 // the property cell at compilation time if no cell exists for the | 954 // the property cell at compilation time if no cell exists for the |
| 955 // property. | 955 // property. |
| 956 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 956 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 957 Handle<GlobalObject> global, | 957 Handle<GlobalObject> global, |
| 958 Handle<String> name, | 958 Handle<Name> name, |
| 959 Register scratch, | 959 Register scratch, |
| 960 Label* miss) { | 960 Label* miss) { |
| 961 Handle<JSGlobalPropertyCell> cell = | 961 Handle<JSGlobalPropertyCell> cell = |
| 962 GlobalObject::EnsurePropertyCell(global, name); | 962 GlobalObject::EnsurePropertyCell(global, name); |
| 963 ASSERT(cell->value()->IsTheHole()); | 963 ASSERT(cell->value()->IsTheHole()); |
| 964 __ mov(scratch, Operand(cell)); | 964 __ mov(scratch, Operand(cell)); |
| 965 __ ldr(scratch, | 965 __ ldr(scratch, |
| 966 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 966 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
| 967 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 967 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 968 __ cmp(scratch, ip); | 968 __ cmp(scratch, ip); |
| 969 __ b(ne, miss); | 969 __ b(ne, miss); |
| 970 } | 970 } |
| 971 | 971 |
| 972 | 972 |
| 973 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 973 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
| 974 // from object to (but not including) holder. | 974 // from object to (but not including) holder. |
| 975 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 975 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
| 976 Handle<JSObject> object, | 976 Handle<JSObject> object, |
| 977 Handle<JSObject> holder, | 977 Handle<JSObject> holder, |
| 978 Handle<String> name, | 978 Handle<Name> name, |
| 979 Register scratch, | 979 Register scratch, |
| 980 Label* miss) { | 980 Label* miss) { |
| 981 Handle<JSObject> current = object; | 981 Handle<JSObject> current = object; |
| 982 while (!current.is_identical_to(holder)) { | 982 while (!current.is_identical_to(holder)) { |
| 983 if (current->IsGlobalObject()) { | 983 if (current->IsGlobalObject()) { |
| 984 GenerateCheckPropertyCell(masm, | 984 GenerateCheckPropertyCell(masm, |
| 985 Handle<GlobalObject>::cast(current), | 985 Handle<GlobalObject>::cast(current), |
| 986 name, | 986 name, |
| 987 scratch, | 987 scratch, |
| 988 miss); | 988 miss); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1065 #undef __ | 1065 #undef __ |
| 1066 #define __ ACCESS_MASM(masm()) | 1066 #define __ ACCESS_MASM(masm()) |
| 1067 | 1067 |
| 1068 | 1068 |
| 1069 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1069 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 1070 Register object_reg, | 1070 Register object_reg, |
| 1071 Handle<JSObject> holder, | 1071 Handle<JSObject> holder, |
| 1072 Register holder_reg, | 1072 Register holder_reg, |
| 1073 Register scratch1, | 1073 Register scratch1, |
| 1074 Register scratch2, | 1074 Register scratch2, |
| 1075 Handle<String> name, | 1075 Handle<Name> name, |
| 1076 int save_at_depth, | 1076 int save_at_depth, |
| 1077 Label* miss) { | 1077 Label* miss) { |
| 1078 // Make sure there's no overlap between holder and object registers. | 1078 // Make sure there's no overlap between holder and object registers. |
| 1079 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1079 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 1080 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1080 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 1081 && !scratch2.is(scratch1)); | 1081 && !scratch2.is(scratch1)); |
| 1082 | 1082 |
| 1083 // Keep track of the current object in register reg. | 1083 // Keep track of the current object in register reg. |
| 1084 Register reg = object_reg; | 1084 Register reg = object_reg; |
| 1085 int depth = 0; | 1085 int depth = 0; |
| 1086 | 1086 |
| 1087 if (save_at_depth == depth) { | 1087 if (save_at_depth == depth) { |
| 1088 __ str(reg, MemOperand(sp)); | 1088 __ str(reg, MemOperand(sp)); |
| 1089 } | 1089 } |
| 1090 | 1090 |
| 1091 // Check the maps in the prototype chain. | 1091 // Check the maps in the prototype chain. |
| 1092 // Traverse the prototype chain from the object and do map checks. | 1092 // Traverse the prototype chain from the object and do map checks. |
| 1093 Handle<JSObject> current = object; | 1093 Handle<JSObject> current = object; |
| 1094 while (!current.is_identical_to(holder)) { | 1094 while (!current.is_identical_to(holder)) { |
| 1095 ++depth; | 1095 ++depth; |
| 1096 | 1096 |
| 1097 // Only global objects and objects that do not require access | 1097 // Only global objects and objects that do not require access |
| 1098 // checks are allowed in stubs. | 1098 // checks are allowed in stubs. |
| 1099 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1099 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
| 1100 | 1100 |
| 1101 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1101 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
| 1102 if (!current->HasFastProperties() && | 1102 if (!current->HasFastProperties() && |
| 1103 !current->IsJSGlobalObject() && | 1103 !current->IsJSGlobalObject() && |
| 1104 !current->IsJSGlobalProxy()) { | 1104 !current->IsJSGlobalProxy()) { |
| 1105 if (!name->IsInternalizedString()) { | 1105 if (!name->IsUniqueName()) { |
| 1106 name = factory()->InternalizeString(name); | 1106 ASSERT(name->IsString()); |
| 1107 name = factory()->InternalizeString(Handle<String>::cast(name)); |
| 1107 } | 1108 } |
| 1108 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1109 ASSERT(current->property_dictionary()->FindEntry(*name) == |
| 1109 StringDictionary::kNotFound); | 1110 NameDictionary::kNotFound); |
| 1110 | 1111 |
| 1111 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1112 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 1112 scratch1, scratch2); | 1113 scratch1, scratch2); |
| 1113 | 1114 |
| 1114 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1115 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1115 reg = holder_reg; // From now on the object will be in holder_reg. | 1116 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1116 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1117 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1117 } else { | 1118 } else { |
| 1118 Handle<Map> current_map(current->map()); | 1119 Handle<Map> current_map(current->map()); |
| 1119 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, | 1120 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 } | 1169 } |
| 1169 | 1170 |
| 1170 | 1171 |
| 1171 void StubCompiler::GenerateLoadField(Handle<JSObject> object, | 1172 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
| 1172 Handle<JSObject> holder, | 1173 Handle<JSObject> holder, |
| 1173 Register receiver, | 1174 Register receiver, |
| 1174 Register scratch1, | 1175 Register scratch1, |
| 1175 Register scratch2, | 1176 Register scratch2, |
| 1176 Register scratch3, | 1177 Register scratch3, |
| 1177 PropertyIndex index, | 1178 PropertyIndex index, |
| 1178 Handle<String> name, | 1179 Handle<Name> name, |
| 1179 Label* miss) { | 1180 Label* miss) { |
| 1180 // Check that the receiver isn't a smi. | 1181 // Check that the receiver isn't a smi. |
| 1181 __ JumpIfSmi(receiver, miss); | 1182 __ JumpIfSmi(receiver, miss); |
| 1182 | 1183 |
| 1183 // Check that the maps haven't changed. | 1184 // Check that the maps haven't changed. |
| 1184 Register reg = CheckPrototypes( | 1185 Register reg = CheckPrototypes( |
| 1185 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1186 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
| 1186 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | 1187 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); |
| 1187 __ Ret(); | 1188 __ Ret(); |
| 1188 } | 1189 } |
| 1189 | 1190 |
| 1190 | 1191 |
| 1191 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, | 1192 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
| 1192 Handle<JSObject> holder, | 1193 Handle<JSObject> holder, |
| 1193 Register receiver, | 1194 Register receiver, |
| 1194 Register scratch1, | 1195 Register scratch1, |
| 1195 Register scratch2, | 1196 Register scratch2, |
| 1196 Register scratch3, | 1197 Register scratch3, |
| 1197 Handle<JSFunction> value, | 1198 Handle<JSFunction> value, |
| 1198 Handle<String> name, | 1199 Handle<Name> name, |
| 1199 Label* miss) { | 1200 Label* miss) { |
| 1200 // Check that the receiver isn't a smi. | 1201 // Check that the receiver isn't a smi. |
| 1201 __ JumpIfSmi(receiver, miss); | 1202 __ JumpIfSmi(receiver, miss); |
| 1202 | 1203 |
| 1203 // Check that the maps haven't changed. | 1204 // Check that the maps haven't changed. |
| 1204 CheckPrototypes( | 1205 CheckPrototypes( |
| 1205 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1206 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
| 1206 | 1207 |
| 1207 // Return the constant value. | 1208 // Return the constant value. |
| 1208 __ LoadHeapObject(r0, value); | 1209 __ LoadHeapObject(r0, value); |
| 1209 __ Ret(); | 1210 __ Ret(); |
| 1210 } | 1211 } |
| 1211 | 1212 |
| 1212 | 1213 |
| 1213 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, | 1214 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, |
| 1214 Register name_reg, | 1215 Register name_reg, |
| 1215 Register scratch1, | 1216 Register scratch1, |
| 1216 Register scratch2, | 1217 Register scratch2, |
| 1217 Register scratch3, | 1218 Register scratch3, |
| 1218 Handle<AccessorInfo> callback, | 1219 Handle<AccessorInfo> callback, |
| 1219 Handle<String> name, | 1220 Handle<Name> name, |
| 1220 Label* miss) { | 1221 Label* miss) { |
| 1221 ASSERT(!receiver.is(scratch1)); | 1222 ASSERT(!receiver.is(scratch1)); |
| 1222 ASSERT(!receiver.is(scratch2)); | 1223 ASSERT(!receiver.is(scratch2)); |
| 1223 ASSERT(!receiver.is(scratch3)); | 1224 ASSERT(!receiver.is(scratch3)); |
| 1224 | 1225 |
| 1225 // Load the properties dictionary. | 1226 // Load the properties dictionary. |
| 1226 Register dictionary = scratch1; | 1227 Register dictionary = scratch1; |
| 1227 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 1228 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 1228 | 1229 |
| 1229 // Probe the dictionary. | 1230 // Probe the dictionary. |
| 1230 Label probe_done; | 1231 Label probe_done; |
| 1231 StringDictionaryLookupStub::GeneratePositiveLookup(masm(), | 1232 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), |
| 1232 miss, | 1233 miss, |
| 1233 &probe_done, | 1234 &probe_done, |
| 1234 dictionary, | 1235 dictionary, |
| 1235 name_reg, | 1236 name_reg, |
| 1236 scratch2, | 1237 scratch2, |
| 1237 scratch3); | 1238 scratch3); |
| 1238 __ bind(&probe_done); | 1239 __ bind(&probe_done); |
| 1239 | 1240 |
| 1240 // If probing finds an entry in the dictionary, scratch3 contains the | 1241 // If probing finds an entry in the dictionary, scratch3 contains the |
| 1241 // pointer into the dictionary. Check that the value is the callback. | 1242 // pointer into the dictionary. Check that the value is the callback. |
| 1242 Register pointer = scratch3; | 1243 Register pointer = scratch3; |
| 1243 const int kElementsStartOffset = StringDictionary::kHeaderSize + | 1244 const int kElementsStartOffset = NameDictionary::kHeaderSize + |
| 1244 StringDictionary::kElementsStartIndex * kPointerSize; | 1245 NameDictionary::kElementsStartIndex * kPointerSize; |
| 1245 const int kValueOffset = kElementsStartOffset + kPointerSize; | 1246 const int kValueOffset = kElementsStartOffset + kPointerSize; |
| 1246 __ ldr(scratch2, FieldMemOperand(pointer, kValueOffset)); | 1247 __ ldr(scratch2, FieldMemOperand(pointer, kValueOffset)); |
| 1247 __ cmp(scratch2, Operand(callback)); | 1248 __ cmp(scratch2, Operand(callback)); |
| 1248 __ b(ne, miss); | 1249 __ b(ne, miss); |
| 1249 } | 1250 } |
| 1250 | 1251 |
| 1251 | 1252 |
| 1252 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, | 1253 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, |
| 1253 Handle<JSObject> holder, | 1254 Handle<JSObject> holder, |
| 1254 Register receiver, | 1255 Register receiver, |
| 1255 Register name_reg, | 1256 Register name_reg, |
| 1256 Register scratch1, | 1257 Register scratch1, |
| 1257 Register scratch2, | 1258 Register scratch2, |
| 1258 Register scratch3, | 1259 Register scratch3, |
| 1259 Register scratch4, | 1260 Register scratch4, |
| 1260 Handle<AccessorInfo> callback, | 1261 Handle<AccessorInfo> callback, |
| 1261 Handle<String> name, | 1262 Handle<Name> name, |
| 1262 Label* miss) { | 1263 Label* miss) { |
| 1263 // Check that the receiver isn't a smi. | 1264 // Check that the receiver isn't a smi. |
| 1264 __ JumpIfSmi(receiver, miss); | 1265 __ JumpIfSmi(receiver, miss); |
| 1265 | 1266 |
| 1266 // Check that the maps haven't changed. | 1267 // Check that the maps haven't changed. |
| 1267 Register reg = CheckPrototypes(object, receiver, holder, scratch1, | 1268 Register reg = CheckPrototypes(object, receiver, holder, scratch1, |
| 1268 scratch2, scratch3, name, miss); | 1269 scratch2, scratch3, name, miss); |
| 1269 | 1270 |
| 1270 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1271 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
| 1271 GenerateDictionaryLoadCallback( | 1272 GenerateDictionaryLoadCallback( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 | 1309 |
| 1309 | 1310 |
| 1310 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, | 1311 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, |
| 1311 Handle<JSObject> interceptor_holder, | 1312 Handle<JSObject> interceptor_holder, |
| 1312 LookupResult* lookup, | 1313 LookupResult* lookup, |
| 1313 Register receiver, | 1314 Register receiver, |
| 1314 Register name_reg, | 1315 Register name_reg, |
| 1315 Register scratch1, | 1316 Register scratch1, |
| 1316 Register scratch2, | 1317 Register scratch2, |
| 1317 Register scratch3, | 1318 Register scratch3, |
| 1318 Handle<String> name, | 1319 Handle<Name> name, |
| 1319 Label* miss) { | 1320 Label* miss) { |
| 1320 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1321 ASSERT(interceptor_holder->HasNamedInterceptor()); |
| 1321 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 1322 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
| 1322 | 1323 |
| 1323 // Check that the receiver isn't a smi. | 1324 // Check that the receiver isn't a smi. |
| 1324 __ JumpIfSmi(receiver, miss); | 1325 __ JumpIfSmi(receiver, miss); |
| 1325 | 1326 |
| 1326 // So far the most popular follow ups for interceptor loads are FIELD | 1327 // So far the most popular follow ups for interceptor loads are FIELD |
| 1327 // and CALLBACKS, so inline only them, other cases may be added | 1328 // and CALLBACKS, so inline only them, other cases may be added |
| 1328 // later. | 1329 // later. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 name_reg, interceptor_holder); | 1450 name_reg, interceptor_holder); |
| 1450 | 1451 |
| 1451 ExternalReference ref = | 1452 ExternalReference ref = |
| 1452 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1453 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
| 1453 masm()->isolate()); | 1454 masm()->isolate()); |
| 1454 __ TailCallExternalReference(ref, 6, 1); | 1455 __ TailCallExternalReference(ref, 6, 1); |
| 1455 } | 1456 } |
| 1456 } | 1457 } |
| 1457 | 1458 |
| 1458 | 1459 |
| 1459 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 1460 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
| 1460 if (kind_ == Code::KEYED_CALL_IC) { | 1461 if (kind_ == Code::KEYED_CALL_IC) { |
| 1461 __ cmp(r2, Operand(name)); | 1462 __ cmp(r2, Operand(name)); |
| 1462 __ b(ne, miss); | 1463 __ b(ne, miss); |
| 1463 } | 1464 } |
| 1464 } | 1465 } |
| 1465 | 1466 |
| 1466 | 1467 |
| 1467 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, | 1468 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, |
| 1468 Handle<JSObject> holder, | 1469 Handle<JSObject> holder, |
| 1469 Handle<String> name, | 1470 Handle<Name> name, |
| 1470 Label* miss) { | 1471 Label* miss) { |
| 1471 ASSERT(holder->IsGlobalObject()); | 1472 ASSERT(holder->IsGlobalObject()); |
| 1472 | 1473 |
| 1473 // Get the number of arguments. | 1474 // Get the number of arguments. |
| 1474 const int argc = arguments().immediate(); | 1475 const int argc = arguments().immediate(); |
| 1475 | 1476 |
| 1476 // Get the receiver from the stack. | 1477 // Get the receiver from the stack. |
| 1477 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1478 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 1478 | 1479 |
| 1479 // Check that the maps haven't changed. | 1480 // Check that the maps haven't changed. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1517 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1518 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
| 1518 kind_, | 1519 kind_, |
| 1519 extra_state_); | 1520 extra_state_); |
| 1520 __ Jump(code, RelocInfo::CODE_TARGET); | 1521 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1521 } | 1522 } |
| 1522 | 1523 |
| 1523 | 1524 |
| 1524 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1525 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
| 1525 Handle<JSObject> holder, | 1526 Handle<JSObject> holder, |
| 1526 PropertyIndex index, | 1527 PropertyIndex index, |
| 1527 Handle<String> name) { | 1528 Handle<Name> name) { |
| 1528 // ----------- S t a t e ------------- | 1529 // ----------- S t a t e ------------- |
| 1529 // -- r2 : name | 1530 // -- r2 : name |
| 1530 // -- lr : return address | 1531 // -- lr : return address |
| 1531 // ----------------------------------- | 1532 // ----------------------------------- |
| 1532 Label miss; | 1533 Label miss; |
| 1533 | 1534 |
| 1534 GenerateNameCheck(name, &miss); | 1535 GenerateNameCheck(name, &miss); |
| 1535 | 1536 |
| 1536 const int argc = arguments().immediate(); | 1537 const int argc = arguments().immediate(); |
| 1537 | 1538 |
| (...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2433 GenerateMissBranch(); | 2434 GenerateMissBranch(); |
| 2434 | 2435 |
| 2435 // Return the generated code. | 2436 // Return the generated code. |
| 2436 return GetCode(function); | 2437 return GetCode(function); |
| 2437 } | 2438 } |
| 2438 | 2439 |
| 2439 | 2440 |
| 2440 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, | 2441 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, |
| 2441 Handle<JSObject> holder, | 2442 Handle<JSObject> holder, |
| 2442 Handle<JSFunction> function, | 2443 Handle<JSFunction> function, |
| 2443 Handle<String> name, | 2444 Handle<Name> name, |
| 2444 CheckType check) { | 2445 CheckType check) { |
| 2445 // ----------- S t a t e ------------- | 2446 // ----------- S t a t e ------------- |
| 2446 // -- r2 : name | 2447 // -- r2 : name |
| 2447 // -- lr : return address | 2448 // -- lr : return address |
| 2448 // ----------------------------------- | 2449 // ----------------------------------- |
| 2449 if (HasCustomCallGenerator(function)) { | 2450 if (HasCustomCallGenerator(function)) { |
| 2450 Handle<Code> code = CompileCustomCall(object, holder, | 2451 Handle<Code> code = CompileCustomCall(object, holder, |
| 2451 Handle<JSGlobalPropertyCell>::null(), | 2452 Handle<JSGlobalPropertyCell>::null(), |
| 2452 function, name); | 2453 function, Handle<String>::cast(name)); |
| 2453 // A null handle means bail out to the regular compiler code below. | 2454 // A null handle means bail out to the regular compiler code below. |
| 2454 if (!code.is_null()) return code; | 2455 if (!code.is_null()) return code; |
| 2455 } | 2456 } |
| 2456 | 2457 |
| 2457 Label miss; | 2458 Label miss; |
| 2458 GenerateNameCheck(name, &miss); | 2459 GenerateNameCheck(name, &miss); |
| 2459 | 2460 |
| 2460 // Get the receiver from the stack | 2461 // Get the receiver from the stack |
| 2461 const int argc = arguments().immediate(); | 2462 const int argc = arguments().immediate(); |
| 2462 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2463 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2566 __ bind(&miss); | 2567 __ bind(&miss); |
| 2567 GenerateMissBranch(); | 2568 GenerateMissBranch(); |
| 2568 | 2569 |
| 2569 // Return the generated code. | 2570 // Return the generated code. |
| 2570 return GetCode(function); | 2571 return GetCode(function); |
| 2571 } | 2572 } |
| 2572 | 2573 |
| 2573 | 2574 |
| 2574 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2575 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
| 2575 Handle<JSObject> holder, | 2576 Handle<JSObject> holder, |
| 2576 Handle<String> name) { | 2577 Handle<Name> name) { |
| 2577 // ----------- S t a t e ------------- | 2578 // ----------- S t a t e ------------- |
| 2578 // -- r2 : name | 2579 // -- r2 : name |
| 2579 // -- lr : return address | 2580 // -- lr : return address |
| 2580 // ----------------------------------- | 2581 // ----------------------------------- |
| 2581 Label miss; | 2582 Label miss; |
| 2582 GenerateNameCheck(name, &miss); | 2583 GenerateNameCheck(name, &miss); |
| 2583 | 2584 |
| 2584 // Get the number of arguments. | 2585 // Get the number of arguments. |
| 2585 const int argc = arguments().immediate(); | 2586 const int argc = arguments().immediate(); |
| 2586 LookupResult lookup(isolate()); | 2587 LookupResult lookup(isolate()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2607 // Return the generated code. | 2608 // Return the generated code. |
| 2608 return GetCode(Code::INTERCEPTOR, name); | 2609 return GetCode(Code::INTERCEPTOR, name); |
| 2609 } | 2610 } |
| 2610 | 2611 |
| 2611 | 2612 |
| 2612 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2613 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2613 Handle<JSObject> object, | 2614 Handle<JSObject> object, |
| 2614 Handle<GlobalObject> holder, | 2615 Handle<GlobalObject> holder, |
| 2615 Handle<JSGlobalPropertyCell> cell, | 2616 Handle<JSGlobalPropertyCell> cell, |
| 2616 Handle<JSFunction> function, | 2617 Handle<JSFunction> function, |
| 2617 Handle<String> name) { | 2618 Handle<Name> name) { |
| 2618 // ----------- S t a t e ------------- | 2619 // ----------- S t a t e ------------- |
| 2619 // -- r2 : name | 2620 // -- r2 : name |
| 2620 // -- lr : return address | 2621 // -- lr : return address |
| 2621 // ----------------------------------- | 2622 // ----------------------------------- |
| 2622 if (HasCustomCallGenerator(function)) { | 2623 if (HasCustomCallGenerator(function)) { |
| 2623 Handle<Code> code = CompileCustomCall(object, holder, cell, function, name); | 2624 Handle<Code> code = CompileCustomCall( |
| 2625 object, holder, cell, function, Handle<String>::cast(name)); |
| 2624 // A null handle means bail out to the regular compiler code below. | 2626 // A null handle means bail out to the regular compiler code below. |
| 2625 if (!code.is_null()) return code; | 2627 if (!code.is_null()) return code; |
| 2626 } | 2628 } |
| 2627 | 2629 |
| 2628 Label miss; | 2630 Label miss; |
| 2629 GenerateNameCheck(name, &miss); | 2631 GenerateNameCheck(name, &miss); |
| 2630 | 2632 |
| 2631 // Get the number of arguments. | 2633 // Get the number of arguments. |
| 2632 const int argc = arguments().immediate(); | 2634 const int argc = arguments().immediate(); |
| 2633 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2635 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2663 GenerateMissBranch(); | 2665 GenerateMissBranch(); |
| 2664 | 2666 |
| 2665 // Return the generated code. | 2667 // Return the generated code. |
| 2666 return GetCode(Code::NORMAL, name); | 2668 return GetCode(Code::NORMAL, name); |
| 2667 } | 2669 } |
| 2668 | 2670 |
| 2669 | 2671 |
| 2670 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2672 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
| 2671 int index, | 2673 int index, |
| 2672 Handle<Map> transition, | 2674 Handle<Map> transition, |
| 2673 Handle<String> name) { | 2675 Handle<Name> name) { |
| 2674 // ----------- S t a t e ------------- | 2676 // ----------- S t a t e ------------- |
| 2675 // -- r0 : value | 2677 // -- r0 : value |
| 2676 // -- r1 : receiver | 2678 // -- r1 : receiver |
| 2677 // -- r2 : name | 2679 // -- r2 : name |
| 2678 // -- lr : return address | 2680 // -- lr : return address |
| 2679 // ----------------------------------- | 2681 // ----------------------------------- |
| 2680 Label miss; | 2682 Label miss; |
| 2681 | 2683 |
| 2682 GenerateStoreField(masm(), | 2684 GenerateStoreField(masm(), |
| 2683 object, | 2685 object, |
| 2684 index, | 2686 index, |
| 2685 transition, | 2687 transition, |
| 2686 name, | 2688 name, |
| 2687 r1, r2, r3, r4, | 2689 r1, r2, r3, r4, |
| 2688 &miss); | 2690 &miss); |
| 2689 __ bind(&miss); | 2691 __ bind(&miss); |
| 2690 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2692 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
| 2691 __ Jump(ic, RelocInfo::CODE_TARGET); | 2693 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2692 | 2694 |
| 2693 // Return the generated code. | 2695 // Return the generated code. |
| 2694 return GetCode(transition.is_null() | 2696 return GetCode(transition.is_null() |
| 2695 ? Code::FIELD | 2697 ? Code::FIELD |
| 2696 : Code::MAP_TRANSITION, name); | 2698 : Code::MAP_TRANSITION, name); |
| 2697 } | 2699 } |
| 2698 | 2700 |
| 2699 | 2701 |
| 2700 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2702 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2701 Handle<String> name, | 2703 Handle<Name> name, |
| 2702 Handle<JSObject> receiver, | 2704 Handle<JSObject> receiver, |
| 2703 Handle<JSObject> holder, | 2705 Handle<JSObject> holder, |
| 2704 Handle<AccessorInfo> callback) { | 2706 Handle<AccessorInfo> callback) { |
| 2705 // ----------- S t a t e ------------- | 2707 // ----------- S t a t e ------------- |
| 2706 // -- r0 : value | 2708 // -- r0 : value |
| 2707 // -- r1 : receiver | 2709 // -- r1 : receiver |
| 2708 // -- r2 : name | 2710 // -- r2 : name |
| 2709 // -- lr : return address | 2711 // -- lr : return address |
| 2710 // ----------------------------------- | 2712 // ----------------------------------- |
| 2711 Label miss; | 2713 Label miss; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2775 } | 2777 } |
| 2776 __ Ret(); | 2778 __ Ret(); |
| 2777 } | 2779 } |
| 2778 | 2780 |
| 2779 | 2781 |
| 2780 #undef __ | 2782 #undef __ |
| 2781 #define __ ACCESS_MASM(masm()) | 2783 #define __ ACCESS_MASM(masm()) |
| 2782 | 2784 |
| 2783 | 2785 |
| 2784 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 2786 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
| 2785 Handle<String> name, | 2787 Handle<Name> name, |
| 2786 Handle<JSObject> receiver, | 2788 Handle<JSObject> receiver, |
| 2787 Handle<JSObject> holder, | 2789 Handle<JSObject> holder, |
| 2788 Handle<JSFunction> setter) { | 2790 Handle<JSFunction> setter) { |
| 2789 // ----------- S t a t e ------------- | 2791 // ----------- S t a t e ------------- |
| 2790 // -- r0 : value | 2792 // -- r0 : value |
| 2791 // -- r1 : receiver | 2793 // -- r1 : receiver |
| 2792 // -- r2 : name | 2794 // -- r2 : name |
| 2793 // -- lr : return address | 2795 // -- lr : return address |
| 2794 // ----------------------------------- | 2796 // ----------------------------------- |
| 2795 Label miss; | 2797 Label miss; |
| 2796 | 2798 |
| 2797 // Check that the maps haven't changed. | 2799 // Check that the maps haven't changed. |
| 2798 __ JumpIfSmi(r1, &miss); | 2800 __ JumpIfSmi(r1, &miss); |
| 2799 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); | 2801 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); |
| 2800 | 2802 |
| 2801 GenerateStoreViaSetter(masm(), setter); | 2803 GenerateStoreViaSetter(masm(), setter); |
| 2802 | 2804 |
| 2803 __ bind(&miss); | 2805 __ bind(&miss); |
| 2804 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2806 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
| 2805 __ Jump(ic, RelocInfo::CODE_TARGET); | 2807 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2806 | 2808 |
| 2807 // Return the generated code. | 2809 // Return the generated code. |
| 2808 return GetCode(Code::CALLBACKS, name); | 2810 return GetCode(Code::CALLBACKS, name); |
| 2809 } | 2811 } |
| 2810 | 2812 |
| 2811 | 2813 |
| 2812 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2814 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
| 2813 Handle<JSObject> receiver, | 2815 Handle<JSObject> receiver, |
| 2814 Handle<String> name) { | 2816 Handle<Name> name) { |
| 2815 // ----------- S t a t e ------------- | 2817 // ----------- S t a t e ------------- |
| 2816 // -- r0 : value | 2818 // -- r0 : value |
| 2817 // -- r1 : receiver | 2819 // -- r1 : receiver |
| 2818 // -- r2 : name | 2820 // -- r2 : name |
| 2819 // -- lr : return address | 2821 // -- lr : return address |
| 2820 // ----------------------------------- | 2822 // ----------------------------------- |
| 2821 Label miss; | 2823 Label miss; |
| 2822 | 2824 |
| 2823 // Check that the map of the object hasn't changed. | 2825 // Check that the map of the object hasn't changed. |
| 2824 __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss, | 2826 __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2850 __ Jump(ic, RelocInfo::CODE_TARGET); | 2852 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2851 | 2853 |
| 2852 // Return the generated code. | 2854 // Return the generated code. |
| 2853 return GetCode(Code::INTERCEPTOR, name); | 2855 return GetCode(Code::INTERCEPTOR, name); |
| 2854 } | 2856 } |
| 2855 | 2857 |
| 2856 | 2858 |
| 2857 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2859 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
| 2858 Handle<GlobalObject> object, | 2860 Handle<GlobalObject> object, |
| 2859 Handle<JSGlobalPropertyCell> cell, | 2861 Handle<JSGlobalPropertyCell> cell, |
| 2860 Handle<String> name) { | 2862 Handle<Name> name) { |
| 2861 // ----------- S t a t e ------------- | 2863 // ----------- S t a t e ------------- |
| 2862 // -- r0 : value | 2864 // -- r0 : value |
| 2863 // -- r1 : receiver | 2865 // -- r1 : receiver |
| 2864 // -- r2 : name | 2866 // -- r2 : name |
| 2865 // -- lr : return address | 2867 // -- lr : return address |
| 2866 // ----------------------------------- | 2868 // ----------------------------------- |
| 2867 Label miss; | 2869 Label miss; |
| 2868 | 2870 |
| 2869 // Check that the map of the global has not changed. | 2871 // Check that the map of the global has not changed. |
| 2870 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 2872 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2896 __ Jump(ic, RelocInfo::CODE_TARGET); | 2898 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2897 | 2899 |
| 2898 // Return the generated code. | 2900 // Return the generated code. |
| 2899 return GetCode(Code::NORMAL, name); | 2901 return GetCode(Code::NORMAL, name); |
| 2900 } | 2902 } |
| 2901 | 2903 |
| 2902 | 2904 |
| 2903 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2905 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
| 2904 Handle<JSObject> object, | 2906 Handle<JSObject> object, |
| 2905 Handle<JSObject> last, | 2907 Handle<JSObject> last, |
| 2906 Handle<String> name, | 2908 Handle<Name> name, |
| 2907 Handle<GlobalObject> global) { | 2909 Handle<GlobalObject> global) { |
| 2908 // ----------- S t a t e ------------- | 2910 // ----------- S t a t e ------------- |
| 2909 // -- r0 : receiver | 2911 // -- r0 : receiver |
| 2910 // -- lr : return address | 2912 // -- lr : return address |
| 2911 // ----------------------------------- | 2913 // ----------------------------------- |
| 2912 Label miss; | 2914 Label miss; |
| 2913 | 2915 |
| 2914 // Check that receiver is not a smi. | 2916 // Check that receiver is not a smi. |
| 2915 __ JumpIfSmi(r0, &miss); | 2917 __ JumpIfSmi(r0, &miss); |
| 2916 | 2918 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2954 } | 2956 } |
| 2955 | 2957 |
| 2956 | 2958 |
| 2957 Register* KeyedLoadStubCompiler::registers() { | 2959 Register* KeyedLoadStubCompiler::registers() { |
| 2958 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 2960 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
| 2959 static Register registers[] = { r1, r0, r2, r3, r4, r5 }; | 2961 static Register registers[] = { r1, r0, r2, r3, r4, r5 }; |
| 2960 return registers; | 2962 return registers; |
| 2961 } | 2963 } |
| 2962 | 2964 |
| 2963 | 2965 |
| 2964 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name, | 2966 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, |
| 2965 Register name_reg, | 2967 Register name_reg, |
| 2966 Label* miss) { | 2968 Label* miss) { |
| 2967 __ cmp(name_reg, Operand(name)); | 2969 __ cmp(name_reg, Operand(name)); |
| 2968 __ b(ne, miss); | 2970 __ b(ne, miss); |
| 2969 } | 2971 } |
| 2970 | 2972 |
| 2971 | 2973 |
| 2972 #undef __ | 2974 #undef __ |
| 2973 #define __ ACCESS_MASM(masm) | 2975 #define __ ACCESS_MASM(masm) |
| 2974 | 2976 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3002 } | 3004 } |
| 3003 | 3005 |
| 3004 | 3006 |
| 3005 #undef __ | 3007 #undef __ |
| 3006 #define __ ACCESS_MASM(masm()) | 3008 #define __ ACCESS_MASM(masm()) |
| 3007 | 3009 |
| 3008 | 3010 |
| 3009 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 3011 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
| 3010 Handle<JSObject> receiver, | 3012 Handle<JSObject> receiver, |
| 3011 Handle<JSObject> holder, | 3013 Handle<JSObject> holder, |
| 3012 Handle<String> name, | 3014 Handle<Name> name, |
| 3013 Handle<JSFunction> getter) { | 3015 Handle<JSFunction> getter) { |
| 3014 // ----------- S t a t e ------------- | 3016 // ----------- S t a t e ------------- |
| 3015 // -- r0 : receiver | 3017 // -- r0 : receiver |
| 3016 // -- r2 : name | 3018 // -- r2 : name |
| 3017 // -- lr : return address | 3019 // -- lr : return address |
| 3018 // ----------------------------------- | 3020 // ----------------------------------- |
| 3019 Label miss; | 3021 Label miss; |
| 3020 | 3022 |
| 3021 // Check that the maps haven't changed. | 3023 // Check that the maps haven't changed. |
| 3022 __ JumpIfSmi(r0, &miss); | 3024 __ JumpIfSmi(r0, &miss); |
| 3023 CheckPrototypes(receiver, r0, holder, r3, r4, r1, name, &miss); | 3025 CheckPrototypes(receiver, r0, holder, r3, r4, r1, name, &miss); |
| 3024 | 3026 |
| 3025 GenerateLoadViaGetter(masm(), getter); | 3027 GenerateLoadViaGetter(masm(), getter); |
| 3026 | 3028 |
| 3027 __ bind(&miss); | 3029 __ bind(&miss); |
| 3028 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3030 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 3029 | 3031 |
| 3030 // Return the generated code. | 3032 // Return the generated code. |
| 3031 return GetCode(Code::CALLBACKS, name); | 3033 return GetCode(Code::CALLBACKS, name); |
| 3032 } | 3034 } |
| 3033 | 3035 |
| 3034 | 3036 |
| 3035 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3037 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 3036 Handle<JSObject> object, | 3038 Handle<JSObject> object, |
| 3037 Handle<GlobalObject> holder, | 3039 Handle<GlobalObject> holder, |
| 3038 Handle<JSGlobalPropertyCell> cell, | 3040 Handle<JSGlobalPropertyCell> cell, |
| 3039 Handle<String> name, | 3041 Handle<Name> name, |
| 3040 bool is_dont_delete) { | 3042 bool is_dont_delete) { |
| 3041 // ----------- S t a t e ------------- | 3043 // ----------- S t a t e ------------- |
| 3042 // -- r0 : receiver | 3044 // -- r0 : receiver |
| 3043 // -- r2 : name | 3045 // -- r2 : name |
| 3044 // -- lr : return address | 3046 // -- lr : return address |
| 3045 // ----------------------------------- | 3047 // ----------------------------------- |
| 3046 Label miss; | 3048 Label miss; |
| 3047 | 3049 |
| 3048 // Check that the map of the global has not changed. | 3050 // Check that the map of the global has not changed. |
| 3049 __ JumpIfSmi(r0, &miss); | 3051 __ JumpIfSmi(r0, &miss); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3126 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); | 3128 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); |
| 3127 | 3129 |
| 3128 // Return the generated code. | 3130 // Return the generated code. |
| 3129 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 3131 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
| 3130 } | 3132 } |
| 3131 | 3133 |
| 3132 | 3134 |
| 3133 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 3135 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
| 3134 int index, | 3136 int index, |
| 3135 Handle<Map> transition, | 3137 Handle<Map> transition, |
| 3136 Handle<String> name) { | 3138 Handle<Name> name) { |
| 3137 // ----------- S t a t e ------------- | 3139 // ----------- S t a t e ------------- |
| 3138 // -- r0 : value | 3140 // -- r0 : value |
| 3139 // -- r1 : name | 3141 // -- r1 : name |
| 3140 // -- r2 : receiver | 3142 // -- r2 : receiver |
| 3141 // -- lr : return address | 3143 // -- lr : return address |
| 3142 // ----------------------------------- | 3144 // ----------------------------------- |
| 3143 Label miss; | 3145 Label miss; |
| 3144 | 3146 |
| 3145 Counters* counters = masm()->isolate()->counters(); | 3147 Counters* counters = masm()->isolate()->counters(); |
| 3146 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); | 3148 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4171 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4173 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
| 4172 } | 4174 } |
| 4173 } | 4175 } |
| 4174 | 4176 |
| 4175 | 4177 |
| 4176 #undef __ | 4178 #undef __ |
| 4177 | 4179 |
| 4178 } } // namespace v8::internal | 4180 } } // namespace v8::internal |
| 4179 | 4181 |
| 4180 #endif // V8_TARGET_ARCH_ARM | 4182 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |