Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2048 // to update the property details in the property dictionary to mark | 2048 // to update the property details in the property dictionary to mark |
| 2049 // it as no longer deleted. We deoptimize in that case. | 2049 // it as no longer deleted. We deoptimize in that case. |
| 2050 if (instr->hydrogen()->RequiresHoleCheck()) { | 2050 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2051 __ CompareRoot(Operand(address, 0), Heap::kTheHoleValueRootIndex); | 2051 __ CompareRoot(Operand(address, 0), Heap::kTheHoleValueRootIndex); |
| 2052 DeoptimizeIf(equal, instr->environment()); | 2052 DeoptimizeIf(equal, instr->environment()); |
| 2053 } | 2053 } |
| 2054 | 2054 |
| 2055 // Store the value. | 2055 // Store the value. |
| 2056 __ movq(Operand(address, 0), value); | 2056 __ movq(Operand(address, 0), value); |
| 2057 | 2057 |
| 2058 Label smi_store; | 2058 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 2059 __ JumpIfSmi(value, &smi_store, Label::kNear); | 2059 Label smi_store; |
| 2060 HType type = instr->hydrogen()->value()->type(); | |
| 2061 if (!type.IsHeapNumber() && !type.IsString() && !type.IsNonPrimitive()) { | |
| 2062 __ JumpIfSmi(value, &smi_store, Label::kNear); | |
| 2063 } | |
| 2060 | 2064 |
| 2061 int offset = JSGlobalPropertyCell::kValueOffset - kHeapObjectTag; | 2065 int offset = JSGlobalPropertyCell::kValueOffset - kHeapObjectTag; |
| 2062 __ lea(object, Operand(address, -offset)); | 2066 __ lea(object, Operand(address, -offset)); |
| 2063 // Cells are always in the remembered set. | 2067 // Cells are always in the remembered set. |
| 2064 __ RecordWrite(object, | 2068 __ RecordWrite(object, |
| 2065 address, | 2069 address, |
| 2066 value, | 2070 value, |
| 2067 kSaveFPRegs, | 2071 kSaveFPRegs, |
| 2068 OMIT_REMEMBERED_SET, | 2072 OMIT_REMEMBERED_SET, |
| 2069 OMIT_SMI_CHECK); | 2073 OMIT_SMI_CHECK); |
| 2070 __ bind(&smi_store); | 2074 __ bind(&smi_store); |
| 2075 } | |
| 2071 } | 2076 } |
| 2072 | 2077 |
| 2073 | 2078 |
| 2074 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | 2079 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { |
| 2075 ASSERT(ToRegister(instr->global_object()).is(rdx)); | 2080 ASSERT(ToRegister(instr->global_object()).is(rdx)); |
| 2076 ASSERT(ToRegister(instr->value()).is(rax)); | 2081 ASSERT(ToRegister(instr->value()).is(rax)); |
| 2077 | 2082 |
| 2078 __ Move(rcx, instr->name()); | 2083 __ Move(rcx, instr->name()); |
| 2079 Handle<Code> ic = instr->strict_mode() | 2084 Handle<Code> ic = instr->strict_mode() |
| 2080 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2085 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 2081 : isolate()->builtins()->StoreIC_Initialize(); | 2086 : isolate()->builtins()->StoreIC_Initialize(); |
| 2082 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 2087 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
| 2083 } | 2088 } |
| 2084 | 2089 |
| 2085 | 2090 |
| 2086 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2091 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2087 Register context = ToRegister(instr->context()); | 2092 Register context = ToRegister(instr->context()); |
| 2088 Register result = ToRegister(instr->result()); | 2093 Register result = ToRegister(instr->result()); |
| 2089 __ movq(result, ContextOperand(context, instr->slot_index())); | 2094 __ movq(result, ContextOperand(context, instr->slot_index())); |
| 2090 } | 2095 } |
| 2091 | 2096 |
| 2092 | 2097 |
| 2093 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { | 2098 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { |
| 2094 Register context = ToRegister(instr->context()); | 2099 Register context = ToRegister(instr->context()); |
| 2095 Register value = ToRegister(instr->value()); | 2100 Register value = ToRegister(instr->value()); |
| 2096 __ movq(ContextOperand(context, instr->slot_index()), value); | 2101 __ movq(ContextOperand(context, instr->slot_index()), value); |
| 2097 if (instr->needs_write_barrier()) { | 2102 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 2103 HType type = instr->hydrogen()->value()->type(); | |
| 2104 SmiCheck check_needed = | |
| 2105 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
| 2098 int offset = Context::SlotOffset(instr->slot_index()); | 2106 int offset = Context::SlotOffset(instr->slot_index()); |
| 2099 Register scratch = ToRegister(instr->TempAt(0)); | 2107 Register scratch = ToRegister(instr->TempAt(0)); |
| 2100 __ RecordWriteContextSlot(context, offset, value, scratch, kSaveFPRegs); | 2108 __ RecordWriteContextSlot(context, offset, value, scratch, kSaveFPRegs, |
|
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
| 2109 EMIT_REMEMBERED_SET, check_needed); | |
| 2101 } | 2110 } |
| 2102 } | 2111 } |
| 2103 | 2112 |
| 2104 | 2113 |
| 2105 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2114 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
| 2106 Register object = ToRegister(instr->InputAt(0)); | 2115 Register object = ToRegister(instr->InputAt(0)); |
| 2107 Register result = ToRegister(instr->result()); | 2116 Register result = ToRegister(instr->result()); |
| 2108 if (instr->hydrogen()->is_in_object()) { | 2117 if (instr->hydrogen()->is_in_object()) { |
| 2109 __ movq(result, FieldOperand(object, instr->hydrogen()->offset())); | 2118 __ movq(result, FieldOperand(object, instr->hydrogen()->offset())); |
| 2110 } else { | 2119 } else { |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3054 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 3063 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 3055 Register object = ToRegister(instr->object()); | 3064 Register object = ToRegister(instr->object()); |
| 3056 Register value = ToRegister(instr->value()); | 3065 Register value = ToRegister(instr->value()); |
| 3057 int offset = instr->offset(); | 3066 int offset = instr->offset(); |
| 3058 | 3067 |
| 3059 if (!instr->transition().is_null()) { | 3068 if (!instr->transition().is_null()) { |
| 3060 __ Move(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); | 3069 __ Move(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); |
| 3061 } | 3070 } |
| 3062 | 3071 |
| 3063 // Do the store. | 3072 // Do the store. |
| 3073 HType type = instr->hydrogen()->value()->type(); | |
| 3074 SmiCheck check_needed = | |
| 3075 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
| 3064 if (instr->is_in_object()) { | 3076 if (instr->is_in_object()) { |
| 3065 __ movq(FieldOperand(object, offset), value); | 3077 __ movq(FieldOperand(object, offset), value); |
| 3066 if (instr->needs_write_barrier()) { | 3078 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3067 Register temp = ToRegister(instr->TempAt(0)); | 3079 Register temp = ToRegister(instr->TempAt(0)); |
| 3068 // Update the write barrier for the object for in-object properties. | 3080 // Update the write barrier for the object for in-object properties. |
| 3069 __ RecordWriteField(object, offset, value, temp, kSaveFPRegs); | 3081 __ RecordWriteField(object, offset, value, temp, kSaveFPRegs, |
|
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
| 3082 EMIT_REMEMBERED_SET, check_needed); | |
| 3070 } | 3083 } |
| 3071 } else { | 3084 } else { |
| 3072 Register temp = ToRegister(instr->TempAt(0)); | 3085 Register temp = ToRegister(instr->TempAt(0)); |
| 3073 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); | 3086 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 3074 __ movq(FieldOperand(temp, offset), value); | 3087 __ movq(FieldOperand(temp, offset), value); |
| 3075 if (instr->needs_write_barrier()) { | 3088 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3076 // Update the write barrier for the properties array. | 3089 // Update the write barrier for the properties array. |
| 3077 // object is used as a scratch register. | 3090 // object is used as a scratch register. |
| 3078 __ RecordWriteField(temp, offset, value, object, kSaveFPRegs); | 3091 __ RecordWriteField(temp, offset, value, object, kSaveFPRegs, |
|
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
| 3092 EMIT_REMEMBERED_SET, check_needed); | |
| 3079 } | 3093 } |
| 3080 } | 3094 } |
| 3081 } | 3095 } |
| 3082 | 3096 |
| 3083 | 3097 |
| 3084 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 3098 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 3085 ASSERT(ToRegister(instr->object()).is(rdx)); | 3099 ASSERT(ToRegister(instr->object()).is(rdx)); |
| 3086 ASSERT(ToRegister(instr->value()).is(rax)); | 3100 ASSERT(ToRegister(instr->value()).is(rax)); |
| 3087 | 3101 |
| 3088 __ Move(rcx, instr->hydrogen()->name()); | 3102 __ Move(rcx, instr->hydrogen()->name()); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3175 __ movq(FieldOperand(elements, offset), value); | 3189 __ movq(FieldOperand(elements, offset), value); |
| 3176 } else { | 3190 } else { |
| 3177 __ movq(FieldOperand(elements, | 3191 __ movq(FieldOperand(elements, |
| 3178 key, | 3192 key, |
| 3179 times_pointer_size, | 3193 times_pointer_size, |
| 3180 FixedArray::kHeaderSize), | 3194 FixedArray::kHeaderSize), |
| 3181 value); | 3195 value); |
| 3182 } | 3196 } |
| 3183 | 3197 |
| 3184 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3198 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3199 HType type = instr->hydrogen()->value()->type(); | |
| 3200 SmiCheck check_needed = | |
| 3201 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
| 3185 // Compute address of modified element and store it into key register. | 3202 // Compute address of modified element and store it into key register. |
| 3186 __ lea(key, FieldOperand(elements, | 3203 __ lea(key, FieldOperand(elements, |
| 3187 key, | 3204 key, |
| 3188 times_pointer_size, | 3205 times_pointer_size, |
| 3189 FixedArray::kHeaderSize)); | 3206 FixedArray::kHeaderSize)); |
| 3190 __ RecordWrite(elements, key, value, kSaveFPRegs); | 3207 __ RecordWrite(elements, key, value, kSaveFPRegs, |
|
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
| 3208 EMIT_REMEMBERED_SET, check_needed); | |
| 3191 } | 3209 } |
| 3192 } | 3210 } |
| 3193 | 3211 |
| 3194 | 3212 |
| 3195 void LCodeGen::DoStoreKeyedFastDoubleElement( | 3213 void LCodeGen::DoStoreKeyedFastDoubleElement( |
| 3196 LStoreKeyedFastDoubleElement* instr) { | 3214 LStoreKeyedFastDoubleElement* instr) { |
| 3197 XMMRegister value = ToDoubleRegister(instr->value()); | 3215 XMMRegister value = ToDoubleRegister(instr->value()); |
| 3198 Label have_value; | 3216 Label have_value; |
| 3199 | 3217 |
| 3200 __ ucomisd(value, value); | 3218 __ ucomisd(value, value); |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3968 } | 3986 } |
| 3969 | 3987 |
| 3970 | 3988 |
| 3971 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 3989 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 3972 Register input = ToRegister(instr->InputAt(0)); | 3990 Register input = ToRegister(instr->InputAt(0)); |
| 3973 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 3991 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 3974 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 3992 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 3975 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 3993 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 3976 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 3994 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 3977 | 3995 |
| 3978 Condition final_branch_condition = EmitTypeofIs(true_label, | 3996 Condition final_branch_condition = |
| 3979 false_label, | 3997 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); |
| 3980 input, | 3998 if (final_branch_condition != no_condition) { |
| 3981 instr->type_literal()); | 3999 EmitBranch(true_block, false_block, final_branch_condition); |
| 3982 | 4000 } |
| 3983 EmitBranch(true_block, false_block, final_branch_condition); | |
| 3984 } | 4001 } |
| 3985 | 4002 |
| 3986 | 4003 |
| 3987 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 4004 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
| 3988 Label* false_label, | 4005 Label* false_label, |
| 3989 Register input, | 4006 Register input, |
| 3990 Handle<String> type_name) { | 4007 Handle<String> type_name) { |
| 3991 Condition final_branch_condition = no_condition; | 4008 Condition final_branch_condition = no_condition; |
| 3992 if (type_name->Equals(heap()->number_symbol())) { | 4009 if (type_name->Equals(heap()->number_symbol())) { |
| 3993 __ JumpIfSmi(input, true_label); | 4010 __ JumpIfSmi(input, true_label); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4041 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 4058 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
| 4042 __ j(below, false_label); | 4059 __ j(below, false_label); |
| 4043 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4060 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
| 4044 __ j(above, false_label); | 4061 __ j(above, false_label); |
| 4045 // Check for undetectable objects => false. | 4062 // Check for undetectable objects => false. |
| 4046 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 4063 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
| 4047 Immediate(1 << Map::kIsUndetectable)); | 4064 Immediate(1 << Map::kIsUndetectable)); |
| 4048 final_branch_condition = zero; | 4065 final_branch_condition = zero; |
| 4049 | 4066 |
| 4050 } else { | 4067 } else { |
| 4051 final_branch_condition = never; | |
| 4052 __ jmp(false_label); | 4068 __ jmp(false_label); |
| 4053 } | 4069 } |
| 4054 | 4070 |
| 4055 return final_branch_condition; | 4071 return final_branch_condition; |
| 4056 } | 4072 } |
| 4057 | 4073 |
| 4058 | 4074 |
| 4059 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 4075 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
| 4060 Register temp = ToRegister(instr->TempAt(0)); | 4076 Register temp = ToRegister(instr->TempAt(0)); |
| 4061 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4077 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4196 RegisterEnvironmentForDeoptimization(environment); | 4212 RegisterEnvironmentForDeoptimization(environment); |
| 4197 ASSERT(osr_pc_offset_ == -1); | 4213 ASSERT(osr_pc_offset_ == -1); |
| 4198 osr_pc_offset_ = masm()->pc_offset(); | 4214 osr_pc_offset_ = masm()->pc_offset(); |
| 4199 } | 4215 } |
| 4200 | 4216 |
| 4201 #undef __ | 4217 #undef __ |
| 4202 | 4218 |
| 4203 } } // namespace v8::internal | 4219 } } // namespace v8::internal |
| 4204 | 4220 |
| 4205 #endif // V8_TARGET_ARCH_X64 | 4221 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |