Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 8256016: Eliminate write barrier for global stores at compile time if value stored is a smi. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698