| 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 #include "src/type-feedback-vector.h" | 5 #include "src/type-feedback-vector.h" |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/ic/ic-inl.h" | 8 #include "src/ic/ic-inl.h" |
| 9 #include "src/ic/ic-state.h" | 9 #include "src/ic/ic-state.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 114 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
| 115 | 115 |
| 116 if (kind != other_spec->GetKind(i)) { | 116 if (kind != other_spec->GetKind(i)) { |
| 117 return true; | 117 return true; |
| 118 } | 118 } |
| 119 i += entry_size; | 119 i += entry_size; |
| 120 } | 120 } |
| 121 return false; | 121 return false; |
| 122 } | 122 } |
| 123 | 123 |
| 124 bool TypeFeedbackMetadata::HasFunctionLiteralSlots() { |
| 125 TypeFeedbackMetadataIterator iter(this); |
| 126 Factory* factory = GetIsolate()->factory(); |
| 127 while (iter.HasNext()) { |
| 128 FeedbackVectorSlot slot = iter.Next(); |
| 129 FeedbackVectorSlotKind kind = iter.kind(); |
| 130 switch (kind) { |
| 131 case FeedbackVectorSlotKind::CREATE_CLOSURE: { |
| 132 return true; |
| 133 break; |
| 134 } |
| 135 default: |
| 136 break; |
| 137 } |
| 138 } |
| 139 return false; |
| 140 } |
| 141 |
| 124 bool TypeFeedbackMetadata::DiffersFrom( | 142 bool TypeFeedbackMetadata::DiffersFrom( |
| 125 const TypeFeedbackMetadata* other_metadata) const { | 143 const TypeFeedbackMetadata* other_metadata) const { |
| 126 if (other_metadata->slot_count() != slot_count()) { | 144 if (other_metadata->slot_count() != slot_count()) { |
| 127 return true; | 145 return true; |
| 128 } | 146 } |
| 129 | 147 |
| 130 int slots = slot_count(); | 148 int slots = slot_count(); |
| 131 for (int i = 0; i < slots;) { | 149 for (int i = 0; i < slots;) { |
| 132 FeedbackVectorSlot slot(i); | 150 FeedbackVectorSlot slot(i); |
| 133 FeedbackVectorSlotKind kind = GetKind(slot); | 151 FeedbackVectorSlotKind kind = GetKind(slot); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 if (length == kReservedIndexCount) { | 209 if (length == kReservedIndexCount) { |
| 192 return Handle<TypeFeedbackVector>::cast( | 210 return Handle<TypeFeedbackVector>::cast( |
| 193 factory->empty_type_feedback_vector()); | 211 factory->empty_type_feedback_vector()); |
| 194 } | 212 } |
| 195 | 213 |
| 196 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); | 214 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); |
| 197 array->set_map_no_write_barrier(isolate->heap()->type_feedback_vector_map()); | 215 array->set_map_no_write_barrier(isolate->heap()->type_feedback_vector_map()); |
| 198 array->set(kMetadataIndex, *metadata); | 216 array->set(kMetadataIndex, *metadata); |
| 199 array->set(kInvocationCountIndex, Smi::kZero); | 217 array->set(kInvocationCountIndex, Smi::kZero); |
| 200 | 218 |
| 201 DisallowHeapAllocation no_gc; | |
| 202 | |
| 203 // Ensure we can skip the write barrier | 219 // Ensure we can skip the write barrier |
| 204 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); | 220 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); |
| 221 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); |
| 205 Handle<Oddball> undefined_value = factory->undefined_value(); | 222 Handle<Oddball> undefined_value = factory->undefined_value(); |
| 206 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); | |
| 207 for (int i = 0; i < slot_count;) { | 223 for (int i = 0; i < slot_count;) { |
| 208 FeedbackVectorSlot slot(i); | 224 FeedbackVectorSlot slot(i); |
| 209 FeedbackVectorSlotKind kind = metadata->GetKind(slot); | 225 FeedbackVectorSlotKind kind = metadata->GetKind(slot); |
| 210 int index = TypeFeedbackVector::GetIndex(slot); | 226 int index = TypeFeedbackVector::GetIndex(slot); |
| 211 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 227 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
| 212 | 228 |
| 213 Object* value; | |
| 214 Object* extra_value = *uninitialized_sentinel; | 229 Object* extra_value = *uninitialized_sentinel; |
| 215 switch (kind) { | 230 switch (kind) { |
| 216 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: | 231 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: |
| 217 value = isolate->heap()->empty_weak_cell(); | 232 array->set(index, isolate->heap()->empty_weak_cell(), |
| 233 SKIP_WRITE_BARRIER); |
| 218 break; | 234 break; |
| 219 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: | 235 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: |
| 220 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: | 236 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: |
| 221 value = Smi::kZero; | 237 array->set(index, Smi::kZero, SKIP_WRITE_BARRIER); |
| 222 break; | 238 break; |
| 223 case FeedbackVectorSlotKind::CREATE_CLOSURE: | 239 case FeedbackVectorSlotKind::CREATE_CLOSURE: { |
| 224 // TODO(mvstanton): Root feedback vectors in this location. | 240 Handle<Cell> cell = factory->NewCell(undefined_value); |
| 225 value = isolate->heap()->empty_type_feedback_vector(); | 241 array->set(index, *cell); |
| 226 break; | 242 break; |
| 243 } |
| 227 case FeedbackVectorSlotKind::LITERAL: | 244 case FeedbackVectorSlotKind::LITERAL: |
| 228 value = *undefined_value; | 245 array->set(index, *undefined_value, SKIP_WRITE_BARRIER); |
| 229 break; | 246 break; |
| 230 case FeedbackVectorSlotKind::CALL_IC: | 247 case FeedbackVectorSlotKind::CALL_IC: |
| 231 value = *uninitialized_sentinel; | 248 array->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER); |
| 232 extra_value = Smi::kZero; | 249 extra_value = Smi::kZero; |
| 233 break; | 250 break; |
| 234 case FeedbackVectorSlotKind::LOAD_IC: | 251 case FeedbackVectorSlotKind::LOAD_IC: |
| 235 case FeedbackVectorSlotKind::KEYED_LOAD_IC: | 252 case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
| 236 case FeedbackVectorSlotKind::STORE_IC: | 253 case FeedbackVectorSlotKind::STORE_IC: |
| 237 case FeedbackVectorSlotKind::KEYED_STORE_IC: | 254 case FeedbackVectorSlotKind::KEYED_STORE_IC: |
| 238 case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC: | 255 case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC: |
| 239 case FeedbackVectorSlotKind::GENERAL: | 256 case FeedbackVectorSlotKind::GENERAL: |
| 240 value = *uninitialized_sentinel; | 257 array->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER); |
| 241 break; | 258 break; |
| 242 | 259 |
| 243 case FeedbackVectorSlotKind::INVALID: | 260 case FeedbackVectorSlotKind::INVALID: |
| 244 case FeedbackVectorSlotKind::KINDS_NUMBER: | 261 case FeedbackVectorSlotKind::KINDS_NUMBER: |
| 245 UNREACHABLE(); | 262 UNREACHABLE(); |
| 246 value = Smi::kZero; | 263 array->set(index, Smi::kZero, SKIP_WRITE_BARRIER); |
| 247 break; | 264 break; |
| 248 } | 265 } |
| 249 array->set(index, value, SKIP_WRITE_BARRIER); | |
| 250 for (int j = 1; j < entry_size; j++) { | 266 for (int j = 1; j < entry_size; j++) { |
| 251 array->set(index + j, extra_value, SKIP_WRITE_BARRIER); | 267 array->set(index + j, extra_value, SKIP_WRITE_BARRIER); |
| 252 } | 268 } |
| 253 i += entry_size; | 269 i += entry_size; |
| 254 } | 270 } |
| 255 return Handle<TypeFeedbackVector>::cast(array); | 271 return Handle<TypeFeedbackVector>::cast(array); |
| 256 } | 272 } |
| 257 | 273 |
| 258 // static | 274 // static |
| 259 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( | 275 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( |
| 260 Isolate* isolate, Handle<TypeFeedbackVector> vector) { | 276 Isolate* isolate, Handle<TypeFeedbackVector> vector) { |
| 261 Handle<TypeFeedbackVector> result; | 277 Handle<TypeFeedbackVector> result; |
| 262 result = Handle<TypeFeedbackVector>::cast( | 278 result = Handle<TypeFeedbackVector>::cast( |
| 263 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); | 279 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); |
| 264 return result; | 280 return result; |
| 265 } | 281 } |
| 266 | 282 |
| 267 | |
| 268 // This logic is copied from | 283 // This logic is copied from |
| 269 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. | 284 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. |
| 270 static bool ClearLogic(Isolate* isolate) { | 285 static bool ClearLogic(Isolate* isolate) { |
| 271 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); | 286 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); |
| 272 } | 287 } |
| 273 | 288 |
| 274 | |
| 275 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, | 289 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, |
| 276 bool force_clear) { | 290 bool force_clear) { |
| 277 Isolate* isolate = GetIsolate(); | 291 Isolate* isolate = GetIsolate(); |
| 278 if (!force_clear && !ClearLogic(isolate)) return; | 292 if (!force_clear && !ClearLogic(isolate)) return; |
| 279 | 293 |
| 280 if (this == isolate->heap()->empty_type_feedback_vector()) return; | 294 if (this == isolate->heap()->empty_type_feedback_vector()) return; |
| 281 | 295 |
| 282 Object* uninitialized_sentinel = | 296 Object* uninitialized_sentinel = |
| 283 TypeFeedbackVector::RawUninitializedSentinel(isolate); | 297 TypeFeedbackVector::RawUninitializedSentinel(isolate); |
| 284 Oddball* undefined_value = isolate->heap()->undefined_value(); | 298 Oddball* undefined_value = isolate->heap()->undefined_value(); |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 void StoreDataPropertyInLiteralICNexus::ConfigureMonomorphic( | 1055 void StoreDataPropertyInLiteralICNexus::ConfigureMonomorphic( |
| 1042 Handle<Name> name, Handle<Map> receiver_map) { | 1056 Handle<Name> name, Handle<Map> receiver_map) { |
| 1043 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | 1057 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 1044 | 1058 |
| 1045 SetFeedback(*cell); | 1059 SetFeedback(*cell); |
| 1046 SetFeedbackExtra(*name); | 1060 SetFeedbackExtra(*name); |
| 1047 } | 1061 } |
| 1048 | 1062 |
| 1049 } // namespace internal | 1063 } // namespace internal |
| 1050 } // namespace v8 | 1064 } // namespace v8 |
| OLD | NEW |