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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2504403005: [stubs] KeyedStoreGeneric: inline dictionary property stores (Closed)
Patch Set: ready for review Created 4 years, 1 month 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
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" 4 #include "src/code-stub-assembler.h"
5 #include "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/frames-inl.h" 6 #include "src/frames-inl.h"
7 #include "src/frames.h" 7 #include "src/frames.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 Heap::RootListIndex root_index) { 1328 Heap::RootListIndex root_index) {
1329 if (Heap::RootIsImmortalImmovable(root_index)) { 1329 if (Heap::RootIsImmortalImmovable(root_index)) {
1330 return StoreObjectFieldNoWriteBarrier(object, offset, LoadRoot(root_index)); 1330 return StoreObjectFieldNoWriteBarrier(object, offset, LoadRoot(root_index));
1331 } else { 1331 } else {
1332 return StoreObjectField(object, offset, LoadRoot(root_index)); 1332 return StoreObjectField(object, offset, LoadRoot(root_index));
1333 } 1333 }
1334 } 1334 }
1335 1335
1336 Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node, 1336 Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node,
1337 Node* value, 1337 Node* value,
1338 int additional_offset,
rmcilroy 2016/11/21 17:25:18 Would it be worth reordering these so that you don
Igor Sheludko 2016/11/22 12:05:07 +1. And if you put additional parameter after Writ
Jakob Kummerow 2016/11/22 13:47:57 Done.
1338 WriteBarrierMode barrier_mode, 1339 WriteBarrierMode barrier_mode,
1339 ParameterMode parameter_mode) { 1340 ParameterMode parameter_mode) {
1340 DCHECK(barrier_mode == SKIP_WRITE_BARRIER || 1341 DCHECK(barrier_mode == SKIP_WRITE_BARRIER ||
1341 barrier_mode == UPDATE_WRITE_BARRIER); 1342 barrier_mode == UPDATE_WRITE_BARRIER);
1342 Node* offset = 1343 int header_size =
1343 ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, parameter_mode, 1344 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag;
1344 FixedArray::kHeaderSize - kHeapObjectTag); 1345 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS,
1346 parameter_mode, header_size);
1345 MachineRepresentation rep = MachineRepresentation::kTagged; 1347 MachineRepresentation rep = MachineRepresentation::kTagged;
1346 if (barrier_mode == SKIP_WRITE_BARRIER) { 1348 if (barrier_mode == SKIP_WRITE_BARRIER) {
1347 return StoreNoWriteBarrier(rep, object, offset, value); 1349 return StoreNoWriteBarrier(rep, object, offset, value);
1348 } else { 1350 } else {
1349 return Store(rep, object, offset, value); 1351 return Store(rep, object, offset, value);
1350 } 1352 }
1351 } 1353 }
1352 1354
1353 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( 1355 Node* CodeStubAssembler::StoreFixedDoubleArrayElement(
1354 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { 1356 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) {
(...skipping 2674 matching lines...) Expand 10 before | Expand all | Expand 10 after
4029 Node* capacity = IntPtrRoundUpToPowerOfTwo32( 4031 Node* capacity = IntPtrRoundUpToPowerOfTwo32(
4030 WordShl(at_least_space_for, IntPtrConstant(1))); 4032 WordShl(at_least_space_for, IntPtrConstant(1)));
4031 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); 4033 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity));
4032 } 4034 }
4033 4035
4034 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { 4036 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) {
4035 return Select(IntPtrGreaterThanOrEqual(left, right), left, right, 4037 return Select(IntPtrGreaterThanOrEqual(left, right), left, right,
4036 MachineType::PointerRepresentation()); 4038 MachineType::PointerRepresentation());
4037 } 4039 }
4038 4040
4041 template <class Dictionary>
4042 Node* CodeStubAssembler::GetNumberOfElements(Node* dictionary) {
4043 return LoadFixedArrayElement(
4044 dictionary, IntPtrConstant(Dictionary::kNumberOfElementsIndex), 0,
4045 INTPTR_PARAMETERS);
4046 }
4047
4048 template <class Dictionary>
4049 void CodeStubAssembler::SetNumberOfElements(Node* dictionary,
4050 Node* num_elements_smi) {
4051 StoreFixedArrayElement(
4052 dictionary, IntPtrConstant(Dictionary::kNumberOfElementsIndex),
4053 num_elements_smi, 0, SKIP_WRITE_BARRIER, INTPTR_PARAMETERS);
4054 }
4055
4056 template <class Dictionary>
4057 Node* CodeStubAssembler::GetCapacity(Node* dictionary) {
4058 return LoadFixedArrayElement(dictionary,
4059 IntPtrConstant(Dictionary::kCapacityIndex), 0,
4060 INTPTR_PARAMETERS);
4061 }
4062
4063 template <class Dictionary>
4064 Node* CodeStubAssembler::GetNextEnumerationIndex(Node* dictionary) {
4065 return LoadFixedArrayElement(
4066 dictionary, IntPtrConstant(Dictionary::kNextEnumerationIndexIndex), 0,
4067 INTPTR_PARAMETERS);
4068 }
4069
4070 template <class Dictionary>
4071 void CodeStubAssembler::SetNextEnumerationIndex(Node* dictionary,
4072 Node* next_enum_index_smi) {
4073 StoreFixedArrayElement(
4074 dictionary, IntPtrConstant(Dictionary::kNextEnumerationIndexIndex),
4075 next_enum_index_smi, 0, SKIP_WRITE_BARRIER, INTPTR_PARAMETERS);
4076 }
4077
4039 template <typename Dictionary> 4078 template <typename Dictionary>
4040 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, 4079 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
4041 Node* unique_name, Label* if_found, 4080 Node* unique_name, Label* if_found,
4042 Variable* var_name_index, 4081 Variable* var_name_index,
4043 Label* if_not_found, 4082 Label* if_not_found,
4044 int inlined_probes) { 4083 int inlined_probes,
4084 LookupMode mode) {
4045 CSA_ASSERT(this, IsDictionary(dictionary)); 4085 CSA_ASSERT(this, IsDictionary(dictionary));
4046 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); 4086 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep());
4087 DCHECK_IMPLIES(mode == kFindInsertionIndex,
4088 inlined_probes == 0 && if_found == nullptr);
4047 Comment("NameDictionaryLookup"); 4089 Comment("NameDictionaryLookup");
4048 4090
4049 Node* capacity = SmiUntag(LoadFixedArrayElement( 4091 Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary));
4050 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0,
4051 INTPTR_PARAMETERS));
4052 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); 4092 Node* mask = IntPtrSub(capacity, IntPtrConstant(1));
4053 Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name)); 4093 Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name));
4054 4094
4055 // See Dictionary::FirstProbe(). 4095 // See Dictionary::FirstProbe().
4056 Node* count = IntPtrConstant(0); 4096 Node* count = IntPtrConstant(0);
4057 Node* entry = WordAnd(hash, mask); 4097 Node* entry = WordAnd(hash, mask);
4058 4098
4059 for (int i = 0; i < inlined_probes; i++) { 4099 for (int i = 0; i < inlined_probes; i++) {
4060 Node* index = EntryToIndex<Dictionary>(entry); 4100 Node* index = EntryToIndex<Dictionary>(entry);
4061 var_name_index->Bind(index); 4101 var_name_index->Bind(index);
4062 4102
4063 Node* current = 4103 Node* current =
4064 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); 4104 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS);
4065 GotoIf(WordEqual(current, unique_name), if_found); 4105 GotoIf(WordEqual(current, unique_name), if_found);
4066 4106
4067 // See Dictionary::NextProbe(). 4107 // See Dictionary::NextProbe().
4068 count = IntPtrConstant(i + 1); 4108 count = IntPtrConstant(i + 1);
4069 entry = WordAnd(IntPtrAdd(entry, count), mask); 4109 entry = WordAnd(IntPtrAdd(entry, count), mask);
4070 } 4110 }
4111 if (mode == kFindInsertionIndex) {
4112 // Appease the variable merging algorithm for "Goto(&loop)" below.
4113 var_name_index->Bind(IntPtrConstant(0));
4114 }
4071 4115
4072 Node* undefined = UndefinedConstant(); 4116 Node* undefined = UndefinedConstant();
4117 Node* the_hole = mode == kFindExisting ? nullptr : TheHoleConstant();
4073 4118
4074 Variable var_count(this, MachineType::PointerRepresentation()); 4119 Variable var_count(this, MachineType::PointerRepresentation());
4075 Variable var_entry(this, MachineType::PointerRepresentation()); 4120 Variable var_entry(this, MachineType::PointerRepresentation());
4076 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; 4121 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index};
4077 Label loop(this, 3, loop_vars); 4122 Label loop(this, 3, loop_vars);
4078 var_count.Bind(count); 4123 var_count.Bind(count);
4079 var_entry.Bind(entry); 4124 var_entry.Bind(entry);
4080 Goto(&loop); 4125 Goto(&loop);
4081 Bind(&loop); 4126 Bind(&loop);
4082 { 4127 {
4083 Node* count = var_count.value(); 4128 Node* count = var_count.value();
4084 Node* entry = var_entry.value(); 4129 Node* entry = var_entry.value();
4085 4130
4086 Node* index = EntryToIndex<Dictionary>(entry); 4131 Node* index = EntryToIndex<Dictionary>(entry);
4087 var_name_index->Bind(index); 4132 var_name_index->Bind(index);
4088 4133
4089 Node* current = 4134 Node* current =
4090 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); 4135 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS);
4091 GotoIf(WordEqual(current, undefined), if_not_found); 4136 GotoIf(WordEqual(current, undefined), if_not_found);
4092 GotoIf(WordEqual(current, unique_name), if_found); 4137 if (mode == kFindExisting) {
4138 GotoIf(WordEqual(current, unique_name), if_found);
4139 } else {
4140 DCHECK(mode == kFindInsertionIndex);
Igor Sheludko 2016/11/22 12:05:08 DCHECK_EQ
Jakob Kummerow 2016/11/22 13:47:57 Done. (FWIW, I disagree with the preference -- I t
4141 GotoIf(WordEqual(current, the_hole), if_not_found);
4142 }
4093 4143
4094 // See Dictionary::NextProbe(). 4144 // See Dictionary::NextProbe().
4095 count = IntPtrAdd(count, IntPtrConstant(1)); 4145 count = IntPtrAdd(count, IntPtrConstant(1));
4096 entry = WordAnd(IntPtrAdd(entry, count), mask); 4146 entry = WordAnd(IntPtrAdd(entry, count), mask);
4097 4147
4098 var_count.Bind(count); 4148 var_count.Bind(count);
4099 var_entry.Bind(entry); 4149 var_entry.Bind(entry);
4100 Goto(&loop); 4150 Goto(&loop);
4101 } 4151 }
4102 } 4152 }
4103 4153
4104 // Instantiate template methods to workaround GCC compilation issue. 4154 // Instantiate template methods to workaround GCC compilation issue.
4105 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( 4155 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>(
4106 Node*, Node*, Label*, Variable*, Label*, int); 4156 Node*, Node*, Label*, Variable*, Label*, int, LookupMode);
4107 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>( 4157 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>(
4108 Node*, Node*, Label*, Variable*, Label*, int); 4158 Node*, Node*, Label*, Variable*, Label*, int, LookupMode);
4109 4159
4110 Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) { 4160 Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
4111 // See v8::internal::ComputeIntegerHash() 4161 // See v8::internal::ComputeIntegerHash()
4112 Node* hash = key; 4162 Node* hash = key;
4113 hash = Word32Xor(hash, seed); 4163 hash = Word32Xor(hash, seed);
4114 hash = Int32Add(Word32Xor(hash, Int32Constant(0xffffffff)), 4164 hash = Int32Add(Word32Xor(hash, Int32Constant(0xffffffff)),
4115 Word32Shl(hash, Int32Constant(15))); 4165 Word32Shl(hash, Int32Constant(15)));
4116 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12))); 4166 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12)));
4117 hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2))); 4167 hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2)));
4118 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4))); 4168 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4)));
4119 hash = Int32Mul(hash, Int32Constant(2057)); 4169 hash = Int32Mul(hash, Int32Constant(2057));
4120 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); 4170 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16)));
4121 return Word32And(hash, Int32Constant(0x3fffffff)); 4171 return Word32And(hash, Int32Constant(0x3fffffff));
4122 } 4172 }
4123 4173
4124 template <typename Dictionary> 4174 template <typename Dictionary>
4125 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, 4175 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
4126 Node* intptr_index, 4176 Node* intptr_index,
4127 Label* if_found, 4177 Label* if_found,
4128 Variable* var_entry, 4178 Variable* var_entry,
4129 Label* if_not_found) { 4179 Label* if_not_found) {
4130 CSA_ASSERT(this, IsDictionary(dictionary)); 4180 CSA_ASSERT(this, IsDictionary(dictionary));
4131 DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep()); 4181 DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep());
4132 Comment("NumberDictionaryLookup"); 4182 Comment("NumberDictionaryLookup");
4133 4183
4134 Node* capacity = SmiUntag(LoadFixedArrayElement( 4184 Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary));
4135 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0,
4136 INTPTR_PARAMETERS));
4137 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); 4185 Node* mask = IntPtrSub(capacity, IntPtrConstant(1));
4138 4186
4139 Node* int32_seed; 4187 Node* int32_seed;
4140 if (Dictionary::ShapeT::UsesSeed) { 4188 if (Dictionary::ShapeT::UsesSeed) {
4141 int32_seed = HashSeed(); 4189 int32_seed = HashSeed();
4142 } else { 4190 } else {
4143 int32_seed = Int32Constant(kZeroHashSeed); 4191 int32_seed = Int32Constant(kZeroHashSeed);
4144 } 4192 }
4145 Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed)); 4193 Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed));
4146 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index); 4194 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4190 // See Dictionary::NextProbe(). 4238 // See Dictionary::NextProbe().
4191 count = IntPtrAdd(count, IntPtrConstant(1)); 4239 count = IntPtrAdd(count, IntPtrConstant(1));
4192 entry = WordAnd(IntPtrAdd(entry, count), mask); 4240 entry = WordAnd(IntPtrAdd(entry, count), mask);
4193 4241
4194 var_count.Bind(count); 4242 var_count.Bind(count);
4195 var_entry->Bind(entry); 4243 var_entry->Bind(entry);
4196 Goto(&loop); 4244 Goto(&loop);
4197 } 4245 }
4198 } 4246 }
4199 4247
4248 template <class Dictionary>
4249 void CodeStubAssembler::FindInsertionEntry(Node* dictionary, Node* key,
4250 Variable* var_key_index) {
4251 UNREACHABLE();
4252 }
4253
4254 template <>
4255 void CodeStubAssembler::FindInsertionEntry<NameDictionary>(
4256 Node* dictionary, Node* key, Variable* var_key_index) {
4257 Label done(this);
4258 NameDictionaryLookup<NameDictionary>(dictionary, key, nullptr, var_key_index,
4259 &done, 0, kFindInsertionIndex);
4260 Bind(&done);
4261 }
4262
4263 template <class Dictionary>
4264 void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value,
Igor Sheludko 2016/11/22 12:05:07 This implementation is not fully applicable for Gl
Jakob Kummerow 2016/11/22 13:47:57 Done. (Pulled out the second half as "InsertEntry<
4265 Label* bailout) {
4266 Node* capacity = GetCapacity<Dictionary>(dictionary);
4267 Node* nof = GetNumberOfElements<Dictionary>(dictionary);
4268 Node* new_nof = SmiAdd(nof, SmiConstant(1));
4269 // Require 33% to still be free after adding additional_elements.
4270 // This is a simplification of the C++ implementation's behavior, which
4271 // also rehashes the dictionary when there are too many deleted elements.
4272 // Computing "x + (x >> 1)" on a Smi x does not return a valid Smi!
4273 // But that's OK here because it's only used for a comparison.
4274 Node* required_capacity_pseudo_smi = SmiAdd(new_nof, WordShr(new_nof, 1));
4275 GotoIf(UintPtrLessThan(capacity, required_capacity_pseudo_smi), bailout);
4276 Node* enum_index = nullptr;
4277 if (Dictionary::kIsEnumerable) {
4278 enum_index = GetNextEnumerationIndex<Dictionary>(dictionary);
4279 Node* new_enum_index = SmiAdd(enum_index, SmiConstant(1));
4280 Node* max_enum_index = SmiConstant(
4281 Smi::FromInt(PropertyDetails::DictionaryStorageField::kMax));
Igor Sheludko 2016/11/22 12:05:07 Can you drop Smi::FromInt?
Jakob Kummerow 2016/11/22 13:47:57 Done.
4282 GotoIf(UintPtrGreaterThan(new_enum_index, max_enum_index), bailout);
4283
4284 // No more bailouts after this point.
4285 // Operations from here on can have side effects.
4286
4287 SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index);
4288 } else {
4289 USE(enum_index);
4290 }
4291 SetNumberOfElements<Dictionary>(dictionary, new_nof);
4292
4293 Variable var_key_index(this, MachineType::PointerRepresentation());
4294 FindInsertionEntry<Dictionary>(dictionary, key, &var_key_index);
4295 Node* index = var_key_index.value();
4296 StoreFixedArrayElement(dictionary, index, key, 0, UPDATE_WRITE_BARRIER,
4297 INTPTR_PARAMETERS);
4298 const int kNameToValueOffset =
4299 (Dictionary::kEntryValueIndex - Dictionary::kEntryKeyIndex) *
4300 kPointerSize;
4301 StoreFixedArrayElement(dictionary, index, value, kNameToValueOffset,
4302 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS);
4303 if (Dictionary::kIsEnumerable) {
Igor Sheludko 2016/11/22 12:05:07 Shoudn't we also set details if the dictionary is
Jakob Kummerow 2016/11/22 13:47:57 Oops, good point. Done.
4304 const int kInitialIndex = 0;
4305 PropertyDetails d(NONE, DATA, kInitialIndex, PropertyCellType::kNoCell);
4306 Node* details = SmiConstant(d.AsSmi());
4307 enum_index =
4308 WordShl(enum_index, PropertyDetails::DictionaryStorageField::kShift);
4309 STATIC_ASSERT(kInitialIndex == 0);
4310 details = WordOr(details, enum_index);
4311 const int kNameToDetailsOffset =
4312 (Dictionary::kEntryDetailsIndex - Dictionary::kEntryKeyIndex) *
4313 kPointerSize;
4314 StoreFixedArrayElement(dictionary, index, details, kNameToDetailsOffset,
4315 SKIP_WRITE_BARRIER, INTPTR_PARAMETERS);
4316 }
4317 }
4318
4319 template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*,
4320 Label*);
4321
4200 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, 4322 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name,
4201 Node* descriptors, Node* nof, 4323 Node* descriptors, Node* nof,
4202 Label* if_found, 4324 Label* if_found,
4203 Variable* var_name_index, 4325 Variable* var_name_index,
4204 Label* if_not_found) { 4326 Label* if_not_found) {
4205 Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); 4327 Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0));
4206 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); 4328 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize);
4207 Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor)); 4329 Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor));
4208 4330
4209 BuildFastLoop( 4331 BuildFastLoop(
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
4975 compiler::Node* type_feedback_vector, 5097 compiler::Node* type_feedback_vector,
4976 compiler::Node* slot_id) { 5098 compiler::Node* slot_id) {
4977 // This method is used for binary op and compare feedback. These 5099 // This method is used for binary op and compare feedback. These
4978 // vector nodes are initialized with a smi 0, so we can simply OR 5100 // vector nodes are initialized with a smi 0, so we can simply OR
4979 // our new feedback in place. 5101 // our new feedback in place.
4980 // TODO(interpreter): Consider passing the feedback as Smi already to avoid 5102 // TODO(interpreter): Consider passing the feedback as Smi already to avoid
4981 // the tagging completely. 5103 // the tagging completely.
4982 Node* previous_feedback = 5104 Node* previous_feedback =
4983 LoadFixedArrayElement(type_feedback_vector, slot_id); 5105 LoadFixedArrayElement(type_feedback_vector, slot_id);
4984 Node* combined_feedback = SmiOr(previous_feedback, SmiFromWord32(feedback)); 5106 Node* combined_feedback = SmiOr(previous_feedback, SmiFromWord32(feedback));
4985 StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, 5107 StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, 0,
4986 SKIP_WRITE_BARRIER); 5108 SKIP_WRITE_BARRIER);
4987 } 5109 }
4988 5110
4989 compiler::Node* CodeStubAssembler::LoadReceiverMap(compiler::Node* receiver) { 5111 compiler::Node* CodeStubAssembler::LoadReceiverMap(compiler::Node* receiver) {
4990 Variable var_receiver_map(this, MachineRepresentation::kTagged); 5112 Variable var_receiver_map(this, MachineRepresentation::kTagged);
4991 Label load_smi_map(this, Label::kDeferred), load_receiver_map(this), 5113 Label load_smi_map(this, Label::kDeferred), load_receiver_map(this),
4992 if_result(this); 5114 if_result(this);
4993 5115
4994 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map); 5116 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map);
4995 Bind(&load_smi_map); 5117 Bind(&load_smi_map);
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
5186 // methods for accessing Context. 5308 // methods for accessing Context.
5187 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); 5309 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize);
5188 DCHECK_EQ(Context::SlotOffset(0) + kHeapObjectTag, 5310 DCHECK_EQ(Context::SlotOffset(0) + kHeapObjectTag,
5189 FixedArray::OffsetOfElementAt(0)); 5311 FixedArray::OffsetOfElementAt(0));
5190 if (is_load) { 5312 if (is_load) {
5191 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0, 5313 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0,
5192 INTPTR_PARAMETERS); 5314 INTPTR_PARAMETERS);
5193 CSA_ASSERT(this, WordNotEqual(result, TheHoleConstant())); 5315 CSA_ASSERT(this, WordNotEqual(result, TheHoleConstant()));
5194 var_result.Bind(result); 5316 var_result.Bind(result);
5195 } else { 5317 } else {
5196 StoreFixedArrayElement(the_context, mapped_index, value, 5318 StoreFixedArrayElement(the_context, mapped_index, value, 0,
5197 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS); 5319 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS);
5198 } 5320 }
5199 Goto(&end); 5321 Goto(&end);
5200 } 5322 }
5201 5323
5202 Bind(&if_unmapped); 5324 Bind(&if_unmapped);
5203 { 5325 {
5204 Node* backing_store = LoadFixedArrayElement(elements, IntPtrConstant(1), 0, 5326 Node* backing_store = LoadFixedArrayElement(elements, IntPtrConstant(1), 0,
5205 INTPTR_PARAMETERS); 5327 INTPTR_PARAMETERS);
5206 GotoIf(WordNotEqual(LoadMap(backing_store), FixedArrayMapConstant()), 5328 GotoIf(WordNotEqual(LoadMap(backing_store), FixedArrayMapConstant()),
5207 bailout); 5329 bailout);
5208 5330
5209 Node* backing_store_length = 5331 Node* backing_store_length =
5210 LoadAndUntagFixedArrayBaseLength(backing_store); 5332 LoadAndUntagFixedArrayBaseLength(backing_store);
5211 GotoIf(UintPtrGreaterThanOrEqual(key, backing_store_length), bailout); 5333 GotoIf(UintPtrGreaterThanOrEqual(key, backing_store_length), bailout);
5212 5334
5213 // The key falls into unmapped range. 5335 // The key falls into unmapped range.
5214 if (is_load) { 5336 if (is_load) {
5215 Node* result = 5337 Node* result =
5216 LoadFixedArrayElement(backing_store, key, 0, INTPTR_PARAMETERS); 5338 LoadFixedArrayElement(backing_store, key, 0, INTPTR_PARAMETERS);
5217 GotoIf(WordEqual(result, TheHoleConstant()), bailout); 5339 GotoIf(WordEqual(result, TheHoleConstant()), bailout);
5218 var_result.Bind(result); 5340 var_result.Bind(result);
5219 } else { 5341 } else {
5220 StoreFixedArrayElement(backing_store, key, value, UPDATE_WRITE_BARRIER, 5342 StoreFixedArrayElement(backing_store, key, value, 0, UPDATE_WRITE_BARRIER,
5221 INTPTR_PARAMETERS); 5343 INTPTR_PARAMETERS);
5222 } 5344 }
5223 Goto(&end); 5345 Goto(&end);
5224 } 5346 }
5225 5347
5226 Bind(&end); 5348 Bind(&end);
5227 return var_result.value(); 5349 return var_result.value();
5228 } 5350 }
5229 5351
5230 Node* CodeStubAssembler::LoadScriptContext(Node* context, int context_index) { 5352 Node* CodeStubAssembler::LoadScriptContext(Node* context, int context_index) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
5293 return; 5415 return;
5294 } 5416 }
5295 5417
5296 WriteBarrierMode barrier_mode = 5418 WriteBarrierMode barrier_mode =
5297 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; 5419 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
5298 if (IsFastDoubleElementsKind(kind)) { 5420 if (IsFastDoubleElementsKind(kind)) {
5299 // Make sure we do not store signalling NaNs into double arrays. 5421 // Make sure we do not store signalling NaNs into double arrays.
5300 value = Float64SilenceNaN(value); 5422 value = Float64SilenceNaN(value);
5301 StoreFixedDoubleArrayElement(elements, index, value, mode); 5423 StoreFixedDoubleArrayElement(elements, index, value, mode);
5302 } else { 5424 } else {
5303 StoreFixedArrayElement(elements, index, value, barrier_mode, mode); 5425 StoreFixedArrayElement(elements, index, value, 0, barrier_mode, mode);
5304 } 5426 }
5305 } 5427 }
5306 5428
5307 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, 5429 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
5308 bool is_jsarray, 5430 bool is_jsarray,
5309 ElementsKind elements_kind, 5431 ElementsKind elements_kind,
5310 KeyedAccessStoreMode store_mode, 5432 KeyedAccessStoreMode store_mode,
5311 Label* bailout) { 5433 Label* bailout) {
5312 Node* elements = LoadElements(object); 5434 Node* elements = LoadElements(object);
5313 if (IsFastSmiOrObjectElementsKind(elements_kind) && 5435 if (IsFastSmiOrObjectElementsKind(elements_kind) &&
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
5685 Node* next_site = LoadBufferObject(site_list, 0); 5807 Node* next_site = LoadBufferObject(site_list, 0);
5686 5808
5687 // TODO(mvstanton): This is a store to a weak pointer, which we may want to 5809 // TODO(mvstanton): This is a store to a weak pointer, which we may want to
5688 // mark as such in order to skip the write barrier, once we have a unified 5810 // mark as such in order to skip the write barrier, once we have a unified
5689 // system for weakness. For now we decided to keep it like this because having 5811 // system for weakness. For now we decided to keep it like this because having
5690 // an initial write barrier backed store makes this pointer strong until the 5812 // an initial write barrier backed store makes this pointer strong until the
5691 // next GC, and allocation sites are designed to survive several GCs anyway. 5813 // next GC, and allocation sites are designed to survive several GCs anyway.
5692 StoreObjectField(site, AllocationSite::kWeakNextOffset, next_site); 5814 StoreObjectField(site, AllocationSite::kWeakNextOffset, next_site);
5693 StoreNoWriteBarrier(MachineRepresentation::kTagged, site_list, site); 5815 StoreNoWriteBarrier(MachineRepresentation::kTagged, site_list, site);
5694 5816
5695 StoreFixedArrayElement(feedback_vector, slot, site, UPDATE_WRITE_BARRIER, 5817 StoreFixedArrayElement(feedback_vector, slot, site, 0, UPDATE_WRITE_BARRIER,
5696 CodeStubAssembler::SMI_PARAMETERS); 5818 CodeStubAssembler::SMI_PARAMETERS);
5697 return site; 5819 return site;
5698 } 5820 }
5699 5821
5700 Node* CodeStubAssembler::CreateWeakCellInFeedbackVector(Node* feedback_vector, 5822 Node* CodeStubAssembler::CreateWeakCellInFeedbackVector(Node* feedback_vector,
5701 Node* slot, 5823 Node* slot,
5702 Node* value) { 5824 Node* value) {
5703 Node* size = IntPtrConstant(WeakCell::kSize); 5825 Node* size = IntPtrConstant(WeakCell::kSize);
5704 Node* cell = Allocate(size, CodeStubAssembler::kPretenured); 5826 Node* cell = Allocate(size, CodeStubAssembler::kPretenured);
5705 5827
5706 // Initialize the WeakCell. 5828 // Initialize the WeakCell.
5707 StoreObjectFieldRoot(cell, WeakCell::kMapOffset, Heap::kWeakCellMapRootIndex); 5829 StoreObjectFieldRoot(cell, WeakCell::kMapOffset, Heap::kWeakCellMapRootIndex);
5708 StoreObjectField(cell, WeakCell::kValueOffset, value); 5830 StoreObjectField(cell, WeakCell::kValueOffset, value);
5709 StoreObjectFieldRoot(cell, WeakCell::kNextOffset, 5831 StoreObjectFieldRoot(cell, WeakCell::kNextOffset,
5710 Heap::kTheHoleValueRootIndex); 5832 Heap::kTheHoleValueRootIndex);
5711 5833
5712 // Store the WeakCell in the feedback vector. 5834 // Store the WeakCell in the feedback vector.
5713 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 5835 StoreFixedArrayElement(feedback_vector, slot, cell, 0, UPDATE_WRITE_BARRIER,
5714 CodeStubAssembler::SMI_PARAMETERS); 5836 CodeStubAssembler::SMI_PARAMETERS);
5715 return cell; 5837 return cell;
5716 } 5838 }
5717 5839
5718 void CodeStubAssembler::BuildFastLoop( 5840 void CodeStubAssembler::BuildFastLoop(
5719 const CodeStubAssembler::VariableList& vars, 5841 const CodeStubAssembler::VariableList& vars,
5720 MachineRepresentation index_rep, Node* start_index, Node* end_index, 5842 MachineRepresentation index_rep, Node* start_index, Node* end_index,
5721 std::function<void(CodeStubAssembler* assembler, Node* index)> body, 5843 std::function<void(CodeStubAssembler* assembler, Node* index)> body,
5722 int increment, IndexAdvanceMode mode) { 5844 int increment, IndexAdvanceMode mode) {
5723 Variable var(this, index_rep); 5845 Variable var(this, index_rep);
(...skipping 1987 matching lines...) Expand 10 before | Expand all | Expand 10 after
7711 7833
7712 compiler::Node* CodeStubAssembler::IsDebugActive() { 7834 compiler::Node* CodeStubAssembler::IsDebugActive() {
7713 Node* is_debug_active = Load( 7835 Node* is_debug_active = Load(
7714 MachineType::Uint8(), 7836 MachineType::Uint8(),
7715 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); 7837 ExternalConstant(ExternalReference::debug_is_active_address(isolate())));
7716 return WordNotEqual(is_debug_active, Int32Constant(0)); 7838 return WordNotEqual(is_debug_active, Int32Constant(0));
7717 } 7839 }
7718 7840
7719 } // namespace internal 7841 } // namespace internal
7720 } // namespace v8 7842 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698