OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/ic/handler-compiler.h" | 7 #include "src/ic/handler-compiler.h" |
8 | 8 |
9 #include "src/api-arguments.h" | 9 #include "src/api-arguments.h" |
10 #include "src/field-type.h" | 10 #include "src/field-type.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 __ pop(slot); | 128 __ pop(slot); |
129 } | 129 } |
130 | 130 |
131 | 131 |
132 void PropertyHandlerCompiler::DiscardVectorAndSlot() { | 132 void PropertyHandlerCompiler::DiscardVectorAndSlot() { |
133 MacroAssembler* masm = this->masm(); | 133 MacroAssembler* masm = this->masm(); |
134 // Remove vector and slot. | 134 // Remove vector and slot. |
135 __ add(sp, sp, Operand(2 * kPointerSize)); | 135 __ add(sp, sp, Operand(2 * kPointerSize)); |
136 } | 136 } |
137 | 137 |
138 void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { | |
139 // No-op. Return address is in lr register. | |
140 } | |
141 | |
142 void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { | |
143 // No-op. Return address is in lr register. | |
144 } | |
145 | |
146 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( | 138 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( |
147 MacroAssembler* masm, Label* miss_label, Register receiver, | 139 MacroAssembler* masm, Label* miss_label, Register receiver, |
148 Handle<Name> name, Register scratch0, Register scratch1) { | 140 Handle<Name> name, Register scratch0, Register scratch1) { |
149 DCHECK(name->IsUniqueName()); | 141 DCHECK(name->IsUniqueName()); |
150 DCHECK(!receiver.is(scratch0)); | 142 DCHECK(!receiver.is(scratch0)); |
151 Counters* counters = masm->isolate()->counters(); | 143 Counters* counters = masm->isolate()->counters(); |
152 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 144 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
153 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 145 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
154 | 146 |
155 Label done; | 147 Label done; |
(...skipping 26 matching lines...) Expand all Loading... |
182 // Restore the temporarily used register. | 174 // Restore the temporarily used register. |
183 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 175 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
184 | 176 |
185 | 177 |
186 NameDictionaryLookupStub::GenerateNegativeLookup( | 178 NameDictionaryLookupStub::GenerateNegativeLookup( |
187 masm, miss_label, &done, receiver, properties, name, scratch1); | 179 masm, miss_label, &done, receiver, properties, name, scratch1); |
188 __ bind(&done); | 180 __ bind(&done); |
189 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 181 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
190 } | 182 } |
191 | 183 |
192 | |
193 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( | |
194 MacroAssembler* masm, int index, Register result, Label* miss) { | |
195 __ LoadNativeContextSlot(index, result); | |
196 // Load its initial map. The global functions all have initial maps. | |
197 __ ldr(result, | |
198 FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset)); | |
199 // Load the prototype from the initial map. | |
200 __ ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); | |
201 } | |
202 | |
203 | |
204 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( | 184 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( |
205 MacroAssembler* masm, Register receiver, Register scratch1, | 185 MacroAssembler* masm, Register receiver, Register scratch1, |
206 Register scratch2, Label* miss_label) { | 186 Register scratch2, Label* miss_label) { |
207 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 187 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); |
208 __ mov(r0, scratch1); | 188 __ mov(r0, scratch1); |
209 __ Ret(); | 189 __ Ret(); |
210 } | 190 } |
211 | 191 |
212 | 192 |
213 // Generate code to check that a global property cell is empty. Create | 193 // Generate code to check that a global property cell is empty. Create |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 328 |
349 | 329 |
350 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, | 330 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, |
351 Handle<Name> name) { | 331 Handle<Name> name) { |
352 if (!label->is_unused()) { | 332 if (!label->is_unused()) { |
353 __ bind(label); | 333 __ bind(label); |
354 __ mov(this->name(), Operand(name)); | 334 __ mov(this->name(), Operand(name)); |
355 } | 335 } |
356 } | 336 } |
357 | 337 |
358 | |
359 void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { | |
360 __ mov(this->name(), Operand(name)); | |
361 } | |
362 | |
363 | |
364 void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition, | |
365 Register map_reg, | |
366 Register scratch, | |
367 Label* miss) { | |
368 Handle<WeakCell> cell = Map::WeakCellForMap(transition); | |
369 DCHECK(!map_reg.is(scratch)); | |
370 __ LoadWeakValue(map_reg, cell, miss); | |
371 if (transition->CanBeDeprecated()) { | |
372 __ ldr(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset)); | |
373 __ tst(scratch, Operand(Map::Deprecated::kMask)); | |
374 __ b(ne, miss); | |
375 } | |
376 } | |
377 | |
378 | |
379 void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg, | |
380 int descriptor, | |
381 Register value_reg, | |
382 Register scratch, | |
383 Label* miss_label) { | |
384 DCHECK(!map_reg.is(scratch)); | |
385 DCHECK(!map_reg.is(value_reg)); | |
386 DCHECK(!value_reg.is(scratch)); | |
387 __ LoadInstanceDescriptors(map_reg, scratch); | |
388 __ ldr(scratch, | |
389 FieldMemOperand(scratch, DescriptorArray::GetValueOffset(descriptor))); | |
390 __ cmp(value_reg, scratch); | |
391 __ b(ne, miss_label); | |
392 } | |
393 | |
394 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(FieldType* field_type, | |
395 Register value_reg, | |
396 Label* miss_label) { | |
397 Register map_reg = scratch1(); | |
398 Register scratch = scratch2(); | |
399 DCHECK(!value_reg.is(map_reg)); | |
400 DCHECK(!value_reg.is(scratch)); | |
401 __ JumpIfSmi(value_reg, miss_label); | |
402 if (field_type->IsClass()) { | |
403 __ ldr(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); | |
404 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), | |
405 scratch); | |
406 __ b(ne, miss_label); | |
407 } | |
408 } | |
409 | |
410 void PropertyHandlerCompiler::GenerateAccessCheck( | 338 void PropertyHandlerCompiler::GenerateAccessCheck( |
411 Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2, | 339 Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2, |
412 Label* miss, bool compare_native_contexts_only) { | 340 Label* miss, bool compare_native_contexts_only) { |
413 Label done; | 341 Label done; |
414 // Load current native context. | 342 // Load current native context. |
415 __ ldr(scratch1, NativeContextMemOperand()); | 343 __ ldr(scratch1, NativeContextMemOperand()); |
416 // Load expected native context. | 344 // Load expected native context. |
417 __ LoadWeakValue(scratch2, native_context_cell, miss); | 345 __ LoadWeakValue(scratch2, native_context_cell, miss); |
418 __ cmp(scratch1, scratch2); | 346 __ cmp(scratch1, scratch2); |
419 | 347 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 if (!miss->is_unused()) { | 459 if (!miss->is_unused()) { |
532 Label success; | 460 Label success; |
533 __ b(&success); | 461 __ b(&success); |
534 GenerateRestoreName(miss, name); | 462 GenerateRestoreName(miss, name); |
535 if (IC::ICUseVector(kind())) PopVectorAndSlot(); | 463 if (IC::ICUseVector(kind())) PopVectorAndSlot(); |
536 TailCallBuiltin(masm(), MissBuiltin(kind())); | 464 TailCallBuiltin(masm(), MissBuiltin(kind())); |
537 __ bind(&success); | 465 __ bind(&success); |
538 } | 466 } |
539 } | 467 } |
540 | 468 |
541 | |
542 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { | |
543 // Return the constant value. | |
544 __ Move(r0, value); | |
545 __ Ret(); | |
546 } | |
547 | |
548 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( | 469 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( |
549 LookupIterator* it, Register holder_reg) { | 470 LookupIterator* it, Register holder_reg) { |
550 DCHECK(holder()->HasNamedInterceptor()); | 471 DCHECK(holder()->HasNamedInterceptor()); |
551 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); | 472 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); |
552 | 473 |
553 // Compile the interceptor call, followed by inline code to load the | 474 // Compile the interceptor call, followed by inline code to load the |
554 // property from further up the prototype chain if the call fails. | 475 // property from further up the prototype chain if the call fails. |
555 // Check that the maps haven't changed. | 476 // Check that the maps haven't changed. |
556 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); | 477 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); |
557 | 478 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 // Return the generated code. | 607 // Return the generated code. |
687 return GetCode(kind(), name); | 608 return GetCode(kind(), name); |
688 } | 609 } |
689 | 610 |
690 | 611 |
691 #undef __ | 612 #undef __ |
692 } // namespace internal | 613 } // namespace internal |
693 } // namespace v8 | 614 } // namespace v8 |
694 | 615 |
695 #endif // V8_TARGET_ARCH_ARM | 616 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |