Chromium Code Reviews| 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 19 matching lines...) Expand all Loading... | |
| 30 } | 30 } |
| 31 | 31 |
| 32 | 32 |
| 33 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( | 33 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( |
| 34 FeedbackVectorSlot slot) const { | 34 FeedbackVectorSlot slot) const { |
| 35 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 35 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 36 int data = Smi::cast(get(index))->value(); | 36 int data = Smi::cast(get(index))->value(); |
| 37 return VectorICComputer::decode(data, slot.ToInt()); | 37 return VectorICComputer::decode(data, slot.ToInt()); |
| 38 } | 38 } |
| 39 | 39 |
| 40 int TypeFeedbackMetadata::GetParameter(int parameter_index) const { | |
| 41 FixedArray* parameters = FixedArray::cast(get(kParametersTableIndex)); | |
| 42 return Smi::cast(parameters->get(parameter_index))->value(); | |
| 43 } | |
| 44 | |
| 40 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, | 45 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, |
| 41 FeedbackVectorSlotKind kind) { | 46 FeedbackVectorSlotKind kind) { |
| 42 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 47 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 43 int data = Smi::cast(get(index))->value(); | 48 int data = Smi::cast(get(index))->value(); |
| 44 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); | 49 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); |
| 45 set(index, Smi::FromInt(new_data)); | 50 set(index, Smi::FromInt(new_data)); |
| 46 } | 51 } |
| 47 | 52 |
| 48 | 53 |
| 49 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( | 54 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 } | 89 } |
| 85 | 90 |
| 86 Handle<TypeFeedbackMetadata> metadata = | 91 Handle<TypeFeedbackMetadata> metadata = |
| 87 Handle<TypeFeedbackMetadata>::cast(array); | 92 Handle<TypeFeedbackMetadata>::cast(array); |
| 88 | 93 |
| 89 for (int i = 0; i < slot_count; i++) { | 94 for (int i = 0; i < slot_count; i++) { |
| 90 FeedbackVectorSlotKind kind = spec->GetKind(i); | 95 FeedbackVectorSlotKind kind = spec->GetKind(i); |
| 91 metadata->SetKind(FeedbackVectorSlot(i), kind); | 96 metadata->SetKind(FeedbackVectorSlot(i), kind); |
| 92 } | 97 } |
| 93 | 98 |
| 99 if (spec->parameters_count() > 0) { | |
| 100 const int parameters_count = spec->parameters_count(); | |
| 101 Handle<FixedArray> params_array = | |
| 102 factory->NewFixedArray(parameters_count, TENURED); | |
| 103 for (int i = 0; i < parameters_count; i++) { | |
| 104 params_array->set(i, Smi::FromInt(spec->GetParameter(i))); | |
| 105 } | |
| 106 metadata->set(kParametersTableIndex, *params_array); | |
| 107 } else { | |
| 108 metadata->set(kParametersTableIndex, *factory->empty_fixed_array()); | |
| 109 } | |
| 110 | |
| 94 // It's important that the TypeFeedbackMetadata have a COW map, since it's | 111 // It's important that the TypeFeedbackMetadata have a COW map, since it's |
| 95 // pointed to by both a SharedFunctionInfo and indirectly by closures through | 112 // pointed to by both a SharedFunctionInfo and indirectly by closures through |
| 96 // the TypeFeedbackVector. The serializer uses the COW map type to decide | 113 // the TypeFeedbackVector. The serializer uses the COW map type to decide |
| 97 // this object belongs in the startup snapshot and not the partial | 114 // this object belongs in the startup snapshot and not the partial |
| 98 // snapshot(s). | 115 // snapshot(s). |
| 99 metadata->set_map(isolate->heap()->fixed_cow_array_map()); | 116 metadata->set_map(isolate->heap()->fixed_cow_array_map()); |
| 100 | 117 |
| 101 return metadata; | 118 return metadata; |
| 102 } | 119 } |
| 103 | 120 |
| 104 | 121 |
| 105 bool TypeFeedbackMetadata::SpecDiffersFrom( | 122 bool TypeFeedbackMetadata::SpecDiffersFrom( |
| 106 const FeedbackVectorSpec* other_spec) const { | 123 const FeedbackVectorSpec* other_spec) const { |
| 107 if (other_spec->slots() != slot_count()) { | 124 if (other_spec->slots() != slot_count()) { |
| 108 return true; | 125 return true; |
| 109 } | 126 } |
| 110 | 127 |
| 111 int slots = slot_count(); | 128 int slots = slot_count(); |
| 129 int parameter_index = 0; | |
| 112 for (int i = 0; i < slots;) { | 130 for (int i = 0; i < slots;) { |
| 113 FeedbackVectorSlot slot(i); | 131 FeedbackVectorSlot slot(i); |
| 114 FeedbackVectorSlotKind kind = GetKind(slot); | 132 FeedbackVectorSlotKind kind = GetKind(slot); |
| 115 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 133 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
| 116 | 134 |
| 117 if (kind != other_spec->GetKind(i)) { | 135 if (kind != other_spec->GetKind(i)) { |
| 118 return true; | 136 return true; |
| 119 } | 137 } |
| 138 if (SlotRequiresParameter(kind)) { | |
| 139 int parameter = GetParameter(parameter_index); | |
| 140 int other_parameter = other_spec->GetParameter(parameter_index); | |
| 141 if (parameter != other_parameter) { | |
| 142 return true; | |
| 143 } | |
| 144 parameter_index++; | |
| 145 } | |
| 120 i += entry_size; | 146 i += entry_size; |
| 121 } | 147 } |
| 122 return false; | 148 return false; |
| 123 } | 149 } |
| 124 | 150 |
| 125 bool TypeFeedbackMetadata::DiffersFrom( | 151 bool TypeFeedbackMetadata::DiffersFrom( |
| 126 const TypeFeedbackMetadata* other_metadata) const { | 152 const TypeFeedbackMetadata* other_metadata) const { |
| 127 if (other_metadata->slot_count() != slot_count()) { | 153 if (other_metadata->slot_count() != slot_count()) { |
| 128 return true; | 154 return true; |
| 129 } | 155 } |
| 130 | 156 |
| 131 int slots = slot_count(); | 157 int slots = slot_count(); |
| 158 int parameter_index = 0; | |
| 132 for (int i = 0; i < slots;) { | 159 for (int i = 0; i < slots;) { |
| 133 FeedbackVectorSlot slot(i); | 160 FeedbackVectorSlot slot(i); |
| 134 FeedbackVectorSlotKind kind = GetKind(slot); | 161 FeedbackVectorSlotKind kind = GetKind(slot); |
| 135 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 162 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
| 136 if (GetKind(slot) != other_metadata->GetKind(slot)) { | 163 if (GetKind(slot) != other_metadata->GetKind(slot)) { |
| 137 return true; | 164 return true; |
| 138 } | 165 } |
| 166 if (SlotRequiresParameter(kind)) { | |
| 167 if (GetParameter(parameter_index) != | |
| 168 other_metadata->GetParameter(parameter_index)) { | |
| 169 return true; | |
| 170 } | |
| 171 parameter_index++; | |
| 172 } | |
| 139 i += entry_size; | 173 i += entry_size; |
| 140 } | 174 } |
| 141 return false; | 175 return false; |
| 142 } | 176 } |
| 143 | 177 |
| 144 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { | 178 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { |
| 145 switch (kind) { | 179 switch (kind) { |
| 146 case FeedbackVectorSlotKind::INVALID: | 180 case FeedbackVectorSlotKind::INVALID: |
| 147 return "INVALID"; | 181 return "INVALID"; |
| 148 case FeedbackVectorSlotKind::CALL_IC: | 182 case FeedbackVectorSlotKind::CALL_IC: |
| 149 return "CALL_IC"; | 183 return "CALL_IC"; |
| 150 case FeedbackVectorSlotKind::LOAD_IC: | 184 case FeedbackVectorSlotKind::LOAD_IC: |
| 151 return "LOAD_IC"; | 185 return "LOAD_IC"; |
| 152 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: | 186 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: |
| 153 return "LOAD_GLOBAL_IC"; | 187 return "LOAD_GLOBAL_IC"; |
| 154 case FeedbackVectorSlotKind::KEYED_LOAD_IC: | 188 case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
| 155 return "KEYED_LOAD_IC"; | 189 return "KEYED_LOAD_IC"; |
| 156 case FeedbackVectorSlotKind::STORE_IC: | 190 case FeedbackVectorSlotKind::STORE_IC: |
| 157 return "STORE_IC"; | 191 return "STORE_IC"; |
| 158 case FeedbackVectorSlotKind::KEYED_STORE_IC: | 192 case FeedbackVectorSlotKind::KEYED_STORE_IC: |
| 159 return "KEYED_STORE_IC"; | 193 return "KEYED_STORE_IC"; |
| 160 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: | 194 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: |
| 161 return "INTERPRETER_BINARYOP_IC"; | 195 return "INTERPRETER_BINARYOP_IC"; |
| 162 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: | 196 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: |
| 163 return "INTERPRETER_COMPARE_IC"; | 197 return "INTERPRETER_COMPARE_IC"; |
| 198 case FeedbackVectorSlotKind::CREATE_CLOSURE: | |
| 199 return "CREATE_CLOSURE"; | |
| 164 case FeedbackVectorSlotKind::GENERAL: | 200 case FeedbackVectorSlotKind::GENERAL: |
| 165 return "STUB"; | 201 return "STUB"; |
| 166 case FeedbackVectorSlotKind::KINDS_NUMBER: | 202 case FeedbackVectorSlotKind::KINDS_NUMBER: |
| 167 break; | 203 break; |
| 168 } | 204 } |
| 169 UNREACHABLE(); | 205 UNREACHABLE(); |
| 170 return "?"; | 206 return "?"; |
| 171 } | 207 } |
| 172 | 208 |
| 173 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( | 209 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( |
| 174 FeedbackVectorSlot slot) const { | 210 FeedbackVectorSlot slot) const { |
| 175 DCHECK(!is_empty()); | 211 DCHECK(!is_empty()); |
| 176 return metadata()->GetKind(slot); | 212 return metadata()->GetKind(slot); |
| 177 } | 213 } |
| 178 | 214 |
| 215 int TypeFeedbackVector::GetParameter(FeedbackVectorSlot slot) const { | |
| 216 DCHECK(!is_empty()); | |
| 217 DCHECK( | |
| 218 TypeFeedbackMetadata::SlotRequiresParameter(metadata()->GetKind(slot))); | |
| 219 return FixedArray::cast(Get(slot))->length(); | |
| 220 } | |
| 221 | |
| 179 // static | 222 // static |
| 180 Handle<TypeFeedbackVector> TypeFeedbackVector::New( | 223 Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
| 181 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { | 224 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { |
| 182 Factory* factory = isolate->factory(); | 225 Factory* factory = isolate->factory(); |
| 183 | 226 |
| 184 const int slot_count = metadata->slot_count(); | 227 const int slot_count = metadata->slot_count(); |
| 185 const int length = slot_count + kReservedIndexCount; | 228 const int length = slot_count + kReservedIndexCount; |
| 186 if (length == kReservedIndexCount) { | 229 if (length == kReservedIndexCount) { |
| 187 return Handle<TypeFeedbackVector>::cast( | 230 return Handle<TypeFeedbackVector>::cast( |
| 188 factory->empty_type_feedback_vector()); | 231 factory->empty_type_feedback_vector()); |
| 189 } | 232 } |
| 190 | 233 |
| 191 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); | 234 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); |
| 192 array->set(kMetadataIndex, *metadata); | 235 array->set(kMetadataIndex, *metadata); |
| 193 array->set(kInvocationCountIndex, Smi::kZero); | 236 array->set(kInvocationCountIndex, Smi::kZero); |
| 237 int parameter_index = 0; | |
| 238 for (int i = 0; i < slot_count;) { | |
|
Benedikt Meurer
2016/12/11 17:58:09
Hm, this looks expensive. Did you measure the perf
mvstanton
2016/12/21 13:09:13
The performance does seem to be okay.
| |
| 239 FeedbackVectorSlot slot(i); | |
| 240 FeedbackVectorSlotKind kind = metadata->GetKind(slot); | |
| 241 int index = TypeFeedbackVector::GetIndex(slot); | |
| 242 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | |
| 243 | |
| 244 if (kind == FeedbackVectorSlotKind::CREATE_CLOSURE) { | |
| 245 // This fixed array is filled with undefined. | |
| 246 int length = metadata->GetParameter(parameter_index++); | |
| 247 if (length == 0) { | |
| 248 // This is a native function literal. We can always point to | |
| 249 // the empty literals array here. | |
| 250 array->set(index, *factory->empty_literals_array(), SKIP_WRITE_BARRIER); | |
| 251 } else { | |
| 252 Handle<FixedArray> value = factory->NewFixedArray(length); | |
| 253 array->set(index, *value); | |
| 254 } | |
| 255 } | |
| 256 i += entry_size; | |
| 257 } | |
| 194 | 258 |
| 195 DisallowHeapAllocation no_gc; | 259 DisallowHeapAllocation no_gc; |
| 196 | 260 |
| 197 // Ensure we can skip the write barrier | 261 // Ensure we can skip the write barrier |
| 198 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); | 262 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); |
| 199 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); | 263 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); |
| 200 for (int i = 0; i < slot_count;) { | 264 for (int i = 0; i < slot_count;) { |
| 201 FeedbackVectorSlot slot(i); | 265 FeedbackVectorSlot slot(i); |
| 202 FeedbackVectorSlotKind kind = metadata->GetKind(slot); | 266 FeedbackVectorSlotKind kind = metadata->GetKind(slot); |
| 203 int index = TypeFeedbackVector::GetIndex(slot); | 267 int index = TypeFeedbackVector::GetIndex(slot); |
| 204 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 268 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
| 205 | 269 |
| 206 Object* value; | 270 Object* value; |
| 207 if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) { | 271 if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) { |
| 208 value = isolate->heap()->empty_weak_cell(); | 272 value = isolate->heap()->empty_weak_cell(); |
| 209 } else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC || | 273 } else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC || |
| 210 kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) { | 274 kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) { |
| 211 value = Smi::kZero; | 275 value = Smi::kZero; |
| 212 } else { | 276 } else { |
| 213 value = *uninitialized_sentinel; | 277 value = *uninitialized_sentinel; |
| 214 } | 278 } |
| 215 array->set(index, value, SKIP_WRITE_BARRIER); | |
| 216 | 279 |
| 217 value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero | 280 if (kind != FeedbackVectorSlotKind::CREATE_CLOSURE) { |
| 218 : *uninitialized_sentinel; | 281 array->set(index, value, SKIP_WRITE_BARRIER); |
| 219 for (int j = 1; j < entry_size; j++) { | 282 value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero |
| 220 array->set(index + j, value, SKIP_WRITE_BARRIER); | 283 : *uninitialized_sentinel; |
| 284 for (int j = 1; j < entry_size; j++) { | |
| 285 array->set(index + j, value, SKIP_WRITE_BARRIER); | |
| 286 } | |
| 221 } | 287 } |
| 222 i += entry_size; | 288 i += entry_size; |
| 223 } | 289 } |
| 224 return Handle<TypeFeedbackVector>::cast(array); | 290 return Handle<TypeFeedbackVector>::cast(array); |
| 225 } | 291 } |
| 226 | 292 |
| 227 | 293 |
| 228 // static | 294 // static |
| 229 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, | 295 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, |
| 230 FeedbackVectorSlot slot) { | 296 FeedbackVectorSlot slot) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 245 // This logic is copied from | 311 // This logic is copied from |
| 246 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. | 312 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. |
| 247 static bool ClearLogic(Isolate* isolate) { | 313 static bool ClearLogic(Isolate* isolate) { |
| 248 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); | 314 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); |
| 249 } | 315 } |
| 250 | 316 |
| 251 | 317 |
| 252 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, | 318 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, |
| 253 bool force_clear) { | 319 bool force_clear) { |
| 254 Isolate* isolate = GetIsolate(); | 320 Isolate* isolate = GetIsolate(); |
| 321 if (!force_clear && !ClearLogic(isolate)) return; | |
| 255 | 322 |
| 256 if (!force_clear && !ClearLogic(isolate)) return; | 323 if (this == isolate->heap()->empty_type_feedback_vector()) return; |
| 257 | 324 |
| 258 Object* uninitialized_sentinel = | 325 Object* uninitialized_sentinel = |
| 259 TypeFeedbackVector::RawUninitializedSentinel(isolate); | 326 TypeFeedbackVector::RawUninitializedSentinel(isolate); |
| 260 | 327 |
| 261 TypeFeedbackMetadataIterator iter(metadata()); | 328 TypeFeedbackMetadataIterator iter(metadata()); |
| 262 while (iter.HasNext()) { | 329 while (iter.HasNext()) { |
| 263 FeedbackVectorSlot slot = iter.Next(); | 330 FeedbackVectorSlot slot = iter.Next(); |
| 264 FeedbackVectorSlotKind kind = iter.kind(); | 331 FeedbackVectorSlotKind kind = iter.kind(); |
| 265 | 332 |
| 266 Object* obj = Get(slot); | 333 Object* obj = Get(slot); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 296 nexus.Clear(shared->code()); | 363 nexus.Clear(shared->code()); |
| 297 break; | 364 break; |
| 298 } | 365 } |
| 299 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: | 366 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: |
| 300 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: { | 367 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: { |
| 301 DCHECK(Get(slot)->IsSmi()); | 368 DCHECK(Get(slot)->IsSmi()); |
| 302 // don't clear these smi slots. | 369 // don't clear these smi slots. |
| 303 // Set(slot, Smi::kZero); | 370 // Set(slot, Smi::kZero); |
| 304 break; | 371 break; |
| 305 } | 372 } |
| 373 case FeedbackVectorSlotKind::CREATE_CLOSURE: { | |
| 374 // Fill the array with undefined. | |
| 375 FixedArray* array = FixedArray::cast(Get(slot)); | |
| 376 for (int i = 0; i < array->length(); i++) { | |
| 377 array->set_undefined(i); | |
| 378 } | |
| 379 break; | |
| 380 } | |
| 306 case FeedbackVectorSlotKind::GENERAL: { | 381 case FeedbackVectorSlotKind::GENERAL: { |
| 307 if (obj->IsHeapObject()) { | 382 if (obj->IsHeapObject()) { |
| 308 InstanceType instance_type = | 383 InstanceType instance_type = |
| 309 HeapObject::cast(obj)->map()->instance_type(); | 384 HeapObject::cast(obj)->map()->instance_type(); |
| 310 // AllocationSites are exempt from clearing. They don't store Maps | 385 // AllocationSites are exempt from clearing. They don't store Maps |
| 311 // or Code pointers which can cause memory leaks if not cleared | 386 // or Code pointers which can cause memory leaks if not cleared |
| 312 // regularly. | 387 // regularly. |
| 313 if (instance_type != ALLOCATION_SITE_TYPE) { | 388 if (instance_type != ALLOCATION_SITE_TYPE) { |
| 314 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); | 389 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); |
| 315 } | 390 } |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 return BinaryOperationHintFromFeedback(feedback); | 1057 return BinaryOperationHintFromFeedback(feedback); |
| 983 } | 1058 } |
| 984 | 1059 |
| 985 CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const { | 1060 CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const { |
| 986 int feedback = Smi::cast(GetFeedback())->value(); | 1061 int feedback = Smi::cast(GetFeedback())->value(); |
| 987 return CompareOperationHintFromFeedback(feedback); | 1062 return CompareOperationHintFromFeedback(feedback); |
| 988 } | 1063 } |
| 989 | 1064 |
| 990 } // namespace internal | 1065 } // namespace internal |
| 991 } // namespace v8 | 1066 } // namespace v8 |
| OLD | NEW |