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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 } | 197 } |
198 | 198 |
199 | 199 |
200 // Generate code to check that a global property cell is empty. Create | 200 // Generate code to check that a global property cell is empty. Create |
201 // the property cell at compilation time if no cell exists for the | 201 // the property cell at compilation time if no cell exists for the |
202 // property. | 202 // property. |
203 void PropertyHandlerCompiler::GenerateCheckPropertyCell( | 203 void PropertyHandlerCompiler::GenerateCheckPropertyCell( |
204 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, | 204 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, |
205 Register scratch, Label* miss) { | 205 Register scratch, Label* miss) { |
206 Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name); | 206 Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name); |
207 DCHECK(cell->value()->IsTheHole()); | 207 Isolate* isolate = masm->isolate(); |
208 Handle<WeakCell> weak_cell = masm->isolate()->factory()->NewWeakCell(cell); | 208 DCHECK(cell->value()->IsTheHole(isolate)); |
| 209 Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); |
209 __ LoadWeakValue(scratch, weak_cell, miss); | 210 __ LoadWeakValue(scratch, weak_cell, miss); |
210 __ ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); | 211 __ ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); |
211 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 212 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
212 __ cmp(scratch, ip); | 213 __ cmp(scratch, ip); |
213 __ b(ne, miss); | 214 __ b(ne, miss); |
214 } | 215 } |
215 | 216 |
216 | 217 |
217 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, | 218 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, |
218 Register holder, Register name, | 219 Register holder, Register name, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 break; | 284 break; |
284 case CallOptimization::kHolderNotFound: | 285 case CallOptimization::kHolderNotFound: |
285 UNREACHABLE(); | 286 UNREACHABLE(); |
286 break; | 287 break; |
287 } | 288 } |
288 | 289 |
289 Isolate* isolate = masm->isolate(); | 290 Isolate* isolate = masm->isolate(); |
290 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 291 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
291 bool call_data_undefined = false; | 292 bool call_data_undefined = false; |
292 // Put call data in place. | 293 // Put call data in place. |
293 if (api_call_info->data()->IsUndefined()) { | 294 if (api_call_info->data()->IsUndefined(isolate)) { |
294 call_data_undefined = true; | 295 call_data_undefined = true; |
295 __ LoadRoot(data, Heap::kUndefinedValueRootIndex); | 296 __ LoadRoot(data, Heap::kUndefinedValueRootIndex); |
296 } else { | 297 } else { |
297 if (optimization.is_constant_call()) { | 298 if (optimization.is_constant_call()) { |
298 __ ldr(data, | 299 __ ldr(data, |
299 FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset)); | 300 FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset)); |
300 __ ldr(data, | 301 __ ldr(data, |
301 FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset)); | 302 FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset)); |
302 __ ldr(data, | 303 __ ldr(data, |
303 FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset)); | 304 FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset)); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 | 563 |
563 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { | 564 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { |
564 // Return the constant value. | 565 // Return the constant value. |
565 __ Move(r0, value); | 566 __ Move(r0, value); |
566 __ Ret(); | 567 __ Ret(); |
567 } | 568 } |
568 | 569 |
569 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( | 570 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( |
570 LookupIterator* it, Register holder_reg) { | 571 LookupIterator* it, Register holder_reg) { |
571 DCHECK(holder()->HasNamedInterceptor()); | 572 DCHECK(holder()->HasNamedInterceptor()); |
572 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); | 573 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); |
573 | 574 |
574 // Compile the interceptor call, followed by inline code to load the | 575 // Compile the interceptor call, followed by inline code to load the |
575 // property from further up the prototype chain if the call fails. | 576 // property from further up the prototype chain if the call fails. |
576 // Check that the maps haven't changed. | 577 // Check that the maps haven't changed. |
577 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); | 578 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); |
578 | 579 |
579 // Preserve the receiver register explicitly whenever it is different from the | 580 // Preserve the receiver register explicitly whenever it is different from the |
580 // holder and it is needed should the interceptor return without any result. | 581 // holder and it is needed should the interceptor return without any result. |
581 // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD | 582 // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD |
582 // case might cause a miss during the prototype check. | 583 // case might cause a miss during the prototype check. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 // Leave the internal frame. | 623 // Leave the internal frame. |
623 } | 624 } |
624 | 625 |
625 GenerateLoadPostInterceptor(it, holder_reg); | 626 GenerateLoadPostInterceptor(it, holder_reg); |
626 } | 627 } |
627 | 628 |
628 | 629 |
629 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { | 630 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { |
630 // Call the runtime system to load the interceptor. | 631 // Call the runtime system to load the interceptor. |
631 DCHECK(holder()->HasNamedInterceptor()); | 632 DCHECK(holder()->HasNamedInterceptor()); |
632 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); | 633 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); |
633 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), | 634 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), |
634 holder()); | 635 holder()); |
635 | 636 |
636 __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor); | 637 __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor); |
637 } | 638 } |
638 | 639 |
639 | 640 |
640 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 641 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
641 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback, | 642 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback, |
642 LanguageMode language_mode) { | 643 LanguageMode language_mode) { |
643 Register holder_reg = Frontend(name); | 644 Register holder_reg = Frontend(name); |
644 | 645 |
645 __ push(receiver()); // receiver | 646 __ push(receiver()); // receiver |
646 __ push(holder_reg); | 647 __ push(holder_reg); |
647 | 648 |
648 // If the callback cannot leak, then push the callback directly, | 649 // If the callback cannot leak, then push the callback directly, |
649 // otherwise wrap it in a weak cell. | 650 // otherwise wrap it in a weak cell. |
650 if (callback->data()->IsUndefined() || callback->data()->IsSmi()) { | 651 if (callback->data()->IsUndefined(isolate()) || callback->data()->IsSmi()) { |
651 __ mov(ip, Operand(callback)); | 652 __ mov(ip, Operand(callback)); |
652 } else { | 653 } else { |
653 Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); | 654 Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); |
654 __ mov(ip, Operand(cell)); | 655 __ mov(ip, Operand(cell)); |
655 } | 656 } |
656 __ push(ip); | 657 __ push(ip); |
657 __ mov(ip, Operand(name)); | 658 __ mov(ip, Operand(name)); |
658 __ Push(ip, value()); | 659 __ Push(ip, value()); |
659 __ Push(Smi::FromInt(language_mode)); | 660 __ Push(Smi::FromInt(language_mode)); |
660 | 661 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 // Return the generated code. | 705 // Return the generated code. |
705 return GetCode(kind(), name); | 706 return GetCode(kind(), name); |
706 } | 707 } |
707 | 708 |
708 | 709 |
709 #undef __ | 710 #undef __ |
710 } // namespace internal | 711 } // namespace internal |
711 } // namespace v8 | 712 } // namespace v8 |
712 | 713 |
713 #endif // V8_TARGET_ARCH_ARM | 714 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |