| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 int id = environment->deoptimization_index(); | 907 int id = environment->deoptimization_index(); |
| 908 Address entry = | 908 Address entry = |
| 909 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 909 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); |
| 910 | 910 |
| 911 if (entry == NULL) { | 911 if (entry == NULL) { |
| 912 Abort(kBailoutWasNotPrepared); | 912 Abort(kBailoutWasNotPrepared); |
| 913 return; | 913 return; |
| 914 } | 914 } |
| 915 | 915 |
| 916 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on A64. | 916 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on A64. |
| 917 TODO_UNIMPLEMENTED("Support for FLAG_deopt_every_n_times >= 2."); |
| 917 if (FLAG_deopt_every_n_times == 1 && | 918 if (FLAG_deopt_every_n_times == 1 && |
| 918 !info()->IsStub() && | 919 !info()->IsStub() && |
| 919 info()->opt_count() == id) { | 920 info()->opt_count() == id) { |
| 920 ASSERT(frame_is_built_); | 921 ASSERT(frame_is_built_); |
| 921 __ Call(entry, RelocInfo::RUNTIME_ENTRY); | 922 __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
| 922 return; | 923 return; |
| 923 } | 924 } |
| 924 | 925 |
| 925 if (info()->ShouldTrapOnDeopt()) { | 926 if (info()->ShouldTrapOnDeopt()) { |
| 926 __ Debug("trap_on_deopt", __LINE__, BREAK); | 927 __ Debug("trap_on_deopt", __LINE__, BREAK); |
| (...skipping 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2605 __ SmiTag(result.X()); | 2606 __ SmiTag(result.X()); |
| 2606 } | 2607 } |
| 2607 } | 2608 } |
| 2608 | 2609 |
| 2609 | 2610 |
| 2610 void LCodeGen::DoDrop(LDrop* instr) { | 2611 void LCodeGen::DoDrop(LDrop* instr) { |
| 2611 __ Drop(instr->count()); | 2612 __ Drop(instr->count()); |
| 2612 } | 2613 } |
| 2613 | 2614 |
| 2614 | 2615 |
| 2616 void LCodeGen::DoDummy(LDummy* instr) { |
| 2617 // Nothing to see here, move on! |
| 2618 } |
| 2619 |
| 2620 |
| 2615 void LCodeGen::DoDummyUse(LDummyUse* instr) { | 2621 void LCodeGen::DoDummyUse(LDummyUse* instr) { |
| 2616 // Nothing to see here, move on! | 2622 // Nothing to see here, move on! |
| 2617 } | 2623 } |
| 2618 | 2624 |
| 2619 | 2625 |
| 2620 void LCodeGen::DoElementsKind(LElementsKind* instr) { | 2626 void LCodeGen::DoElementsKind(LElementsKind* instr) { |
| 2621 Register result = ToRegister(instr->result()); | 2627 Register result = ToRegister(instr->result()); |
| 2622 Register input = ToRegister(instr->value()); | 2628 Register input = ToRegister(instr->value()); |
| 2623 | 2629 |
| 2624 // Load map into result. | 2630 // Load map into result. |
| (...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3420 } | 3426 } |
| 3421 | 3427 |
| 3422 | 3428 |
| 3423 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 3429 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
| 3424 HObjectAccess access = instr->hydrogen()->access(); | 3430 HObjectAccess access = instr->hydrogen()->access(); |
| 3425 int offset = access.offset(); | 3431 int offset = access.offset(); |
| 3426 Register object = ToRegister(instr->object()); | 3432 Register object = ToRegister(instr->object()); |
| 3427 | 3433 |
| 3428 if (access.IsExternalMemory()) { | 3434 if (access.IsExternalMemory()) { |
| 3429 Register result = ToRegister(instr->result()); | 3435 Register result = ToRegister(instr->result()); |
| 3430 // TODO(all): Does this need an Integer32 accessor? | 3436 __ Load(result, MemOperand(object, offset), access.representation()); |
| 3431 if (access.representation().IsByte()) { | |
| 3432 __ Ldrb(result, MemOperand(object, offset)); | |
| 3433 } else { | |
| 3434 __ Ldr(result, MemOperand(object, offset)); | |
| 3435 } | |
| 3436 return; | 3437 return; |
| 3437 } | 3438 } |
| 3438 | 3439 |
| 3439 if (instr->hydrogen()->representation().IsDouble()) { | 3440 if (instr->hydrogen()->representation().IsDouble()) { |
| 3440 FPRegister result = ToDoubleRegister(instr->result()); | 3441 FPRegister result = ToDoubleRegister(instr->result()); |
| 3441 __ Ldr(result, FieldMemOperand(object, offset)); | 3442 __ Ldr(result, FieldMemOperand(object, offset)); |
| 3442 return; | 3443 return; |
| 3443 } | 3444 } |
| 3444 | 3445 |
| 3445 Register result = ToRegister(instr->result()); | 3446 Register result = ToRegister(instr->result()); |
| 3446 Register source; | 3447 Register source; |
| 3447 if (access.IsInobject()) { | 3448 if (access.IsInobject()) { |
| 3448 source = object; | 3449 source = object; |
| 3449 } else { | 3450 } else { |
| 3450 // Load the properties array, using result as a scratch register. | 3451 // Load the properties array, using result as a scratch register. |
| 3451 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 3452 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 3452 source = result; | 3453 source = result; |
| 3453 } | 3454 } |
| 3454 if (access.representation().IsByte()) { | 3455 __ Load(result, FieldMemOperand(source, offset), access.representation()); |
| 3455 __ Ldrb(result, FieldMemOperand(source, offset)); | |
| 3456 } else if (access.representation().IsInteger32()) { | |
| 3457 __ Ldr(result.W(), FieldMemOperand(source, offset)); | |
| 3458 } else { | |
| 3459 __ Ldr(result, FieldMemOperand(source, offset)); | |
| 3460 } | |
| 3461 } | 3456 } |
| 3462 | 3457 |
| 3463 | 3458 |
| 3464 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 3459 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 3465 // LoadIC expects x2 to hold the name, and x0 to hold the receiver. | 3460 // LoadIC expects x2 to hold the name, and x0 to hold the receiver. |
| 3466 ASSERT(ToRegister(instr->object()).is(x0)); | 3461 ASSERT(ToRegister(instr->object()).is(x0)); |
| 3467 __ Mov(x2, Operand(instr->name())); | 3462 __ Mov(x2, Operand(instr->name())); |
| 3468 | 3463 |
| 3469 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 3464 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 3470 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3465 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| (...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4872 Representation representation = instr->representation(); | 4867 Representation representation = instr->representation(); |
| 4873 | 4868 |
| 4874 Register object = ToRegister(instr->object()); | 4869 Register object = ToRegister(instr->object()); |
| 4875 Register temp0 = ToRegister(instr->temp0()); | 4870 Register temp0 = ToRegister(instr->temp0()); |
| 4876 Register temp1 = ToRegister(instr->temp1()); | 4871 Register temp1 = ToRegister(instr->temp1()); |
| 4877 HObjectAccess access = instr->hydrogen()->access(); | 4872 HObjectAccess access = instr->hydrogen()->access(); |
| 4878 int offset = access.offset(); | 4873 int offset = access.offset(); |
| 4879 | 4874 |
| 4880 if (access.IsExternalMemory()) { | 4875 if (access.IsExternalMemory()) { |
| 4881 Register value = ToRegister(instr->value()); | 4876 Register value = ToRegister(instr->value()); |
| 4882 if (representation.IsByte()) { | 4877 __ Store(value, MemOperand(object, offset), representation); |
| 4883 __ Strb(value, MemOperand(object, offset)); | |
| 4884 } else { | |
| 4885 __ Str(value, MemOperand(object, offset)); | |
| 4886 } | |
| 4887 return; | 4878 return; |
| 4888 } | 4879 } |
| 4889 | 4880 |
| 4890 Handle<Map> transition = instr->transition(); | 4881 Handle<Map> transition = instr->transition(); |
| 4891 | 4882 |
| 4892 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 4883 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 4893 Register value = ToRegister(instr->value()); | 4884 Register value = ToRegister(instr->value()); |
| 4894 if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 4885 if (!instr->hydrogen()->value()->type().IsHeapObject()) { |
| 4895 DeoptimizeIfSmi(value, instr->environment()); | 4886 DeoptimizeIfSmi(value, instr->environment()); |
| 4896 } | 4887 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4926 Register destination; | 4917 Register destination; |
| 4927 SmiCheck check_needed = | 4918 SmiCheck check_needed = |
| 4928 instr->hydrogen()->value()->IsHeapObject() | 4919 instr->hydrogen()->value()->IsHeapObject() |
| 4929 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4920 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4930 if (access.IsInobject()) { | 4921 if (access.IsInobject()) { |
| 4931 destination = object; | 4922 destination = object; |
| 4932 } else { | 4923 } else { |
| 4933 __ Ldr(temp0, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 4924 __ Ldr(temp0, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 4934 destination = temp0; | 4925 destination = temp0; |
| 4935 } | 4926 } |
| 4936 if (representation.IsByte()) { | 4927 __ Store(value, FieldMemOperand(destination, offset), representation); |
| 4937 __ Strb(value, FieldMemOperand(destination, offset)); | |
| 4938 } else if (access.representation().IsInteger32()) { | |
| 4939 __ Str(value.W(), FieldMemOperand(destination, offset)); | |
| 4940 } else { | |
| 4941 __ Str(value, FieldMemOperand(destination, offset)); | |
| 4942 } | |
| 4943 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4928 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4944 __ RecordWriteField(destination, | 4929 __ RecordWriteField(destination, |
| 4945 offset, | 4930 offset, |
| 4946 value, // Clobbered. | 4931 value, // Clobbered. |
| 4947 temp1, // Clobbered. | 4932 temp1, // Clobbered. |
| 4948 GetLinkRegisterState(), | 4933 GetLinkRegisterState(), |
| 4949 kSaveFPRegs, | 4934 kSaveFPRegs, |
| 4950 EMIT_REMEMBERED_SET, | 4935 EMIT_REMEMBERED_SET, |
| 4951 check_needed); | 4936 check_needed); |
| 4952 } | 4937 } |
| 4953 } | 4938 } |
| 4954 | 4939 |
| 4955 | 4940 |
| 4956 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 4941 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 4957 ASSERT(ToRegister(instr->value()).is(x0)); | 4942 ASSERT(ToRegister(instr->value()).is(x0)); |
| 4958 ASSERT(ToRegister(instr->object()).is(x1)); | 4943 ASSERT(ToRegister(instr->object()).is(x1)); |
| 4959 | 4944 |
| 4960 // Name must be in x2. | 4945 // Name must be in x2. |
| 4961 __ Mov(x2, Operand(instr->name())); | 4946 __ Mov(x2, Operand(instr->name())); |
| 4962 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 4947 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| 4963 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 4948 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 4964 : isolate()->builtins()->StoreIC_Initialize(); | 4949 : isolate()->builtins()->StoreIC_Initialize(); |
| 4965 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4950 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 4966 } | 4951 } |
| 4967 | 4952 |
| 4968 | 4953 |
| 4969 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4954 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
| 4970 Register left = ToRegister(instr->left()); | 4955 Register left = ToRegister(instr->left()); |
| 4971 Register right = ToRegister(instr->right()); | 4956 Register right = ToRegister(instr->right()); |
| 4972 __ Push(left, right); | 4957 if (FLAG_new_string_add) { |
| 4973 StringAddStub stub(instr->hydrogen()->flags()); | 4958 ASSERT(left.Is(x1)); |
| 4974 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4959 ASSERT(right.Is(x0)); |
| 4960 NewStringAddStub stub(instr->hydrogen()->flags(), |
| 4961 isolate()->heap()->GetPretenureMode()); |
| 4962 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4963 } else { |
| 4964 __ Push(left, right); |
| 4965 StringAddStub stub(instr->hydrogen()->flags()); |
| 4966 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4967 } |
| 4975 } | 4968 } |
| 4976 | 4969 |
| 4977 | 4970 |
| 4978 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4971 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 4979 class DeferredStringCharCodeAt: public LDeferredCode { | 4972 class DeferredStringCharCodeAt: public LDeferredCode { |
| 4980 public: | 4973 public: |
| 4981 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4974 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
| 4982 : LDeferredCode(codegen), instr_(instr) { } | 4975 : LDeferredCode(codegen), instr_(instr) { } |
| 4983 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } | 4976 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } |
| 4984 virtual LInstruction* instr() { return instr_; } | 4977 virtual LInstruction* instr() { return instr_; } |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5551 __ Bind(&out_of_object); | 5544 __ Bind(&out_of_object); |
| 5552 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5545 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5553 // Index is equal to negated out of object property index plus 1. | 5546 // Index is equal to negated out of object property index plus 1. |
| 5554 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5547 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5555 __ Ldr(result, FieldMemOperand(result, | 5548 __ Ldr(result, FieldMemOperand(result, |
| 5556 FixedArray::kHeaderSize - kPointerSize)); | 5549 FixedArray::kHeaderSize - kPointerSize)); |
| 5557 __ Bind(&done); | 5550 __ Bind(&done); |
| 5558 } | 5551 } |
| 5559 | 5552 |
| 5560 } } // namespace v8::internal | 5553 } } // namespace v8::internal |
| OLD | NEW |