| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 namespace v8 { | 52 namespace v8 { |
| 53 namespace internal { | 53 namespace internal { |
| 54 | 54 |
| 55 PropertyDetails::PropertyDetails(Smi* smi) { | 55 PropertyDetails::PropertyDetails(Smi* smi) { |
| 56 value_ = smi->value(); | 56 value_ = smi->value(); |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 Smi* PropertyDetails::AsSmi() { | 60 Smi* PropertyDetails::AsSmi() { |
| 61 return Smi::FromInt(value_); | 61 // Ensure the upper 2 bits have the same value by sign extending it. This is |
| 62 // necessary to be able to use the 31st bit of the property details. |
| 63 int value = value_ << 1; |
| 64 return Smi::FromInt(value >> 1); |
| 62 } | 65 } |
| 63 | 66 |
| 64 | 67 |
| 65 PropertyDetails PropertyDetails::AsDeleted() { | 68 PropertyDetails PropertyDetails::AsDeleted() { |
| 66 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1)); | 69 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1)); |
| 67 return PropertyDetails(smi); | 70 return PropertyDetails(smi); |
| 68 } | 71 } |
| 69 | 72 |
| 70 | 73 |
| 71 #define TYPE_CHECKER(type, instancetype) \ | 74 #define TYPE_CHECKER(type, instancetype) \ |
| (...skipping 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); | 1471 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); |
| 1469 Map* map; | 1472 Map* map; |
| 1470 if (!maybe->To(&map)) return maybe; | 1473 if (!maybe->To(&map)) return maybe; |
| 1471 set_map(map); | 1474 set_map(map); |
| 1472 initialize_elements(); | 1475 initialize_elements(); |
| 1473 | 1476 |
| 1474 return this; | 1477 return this; |
| 1475 } | 1478 } |
| 1476 | 1479 |
| 1477 | 1480 |
| 1478 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* map) { | |
| 1479 ASSERT(this->map()->NumberOfOwnDescriptors() + 1 == | |
| 1480 map->NumberOfOwnDescriptors()); | |
| 1481 if (this->map()->unused_property_fields() == 0) { | |
| 1482 int new_size = properties()->length() + map->unused_property_fields() + 1; | |
| 1483 FixedArray* new_properties; | |
| 1484 MaybeObject* maybe_properties = properties()->CopySize(new_size); | |
| 1485 if (!maybe_properties->To(&new_properties)) return maybe_properties; | |
| 1486 set_properties(new_properties); | |
| 1487 } | |
| 1488 set_map(map); | |
| 1489 return this; | |
| 1490 } | |
| 1491 | |
| 1492 | |
| 1493 MaybeObject* JSObject::TransitionToMap(Map* map) { | 1481 MaybeObject* JSObject::TransitionToMap(Map* map) { |
| 1494 ASSERT(this->map()->inobject_properties() == map->inobject_properties()); | 1482 ASSERT(this->map()->inobject_properties() == map->inobject_properties()); |
| 1495 ElementsKind expected_kind = this->map()->elements_kind(); | 1483 ElementsKind expected_kind = this->map()->elements_kind(); |
| 1496 if (map->elements_kind() != expected_kind) { | 1484 if (map->elements_kind() != expected_kind) { |
| 1497 MaybeObject* maybe_map = map->AsElementsKind(expected_kind); | 1485 MaybeObject* maybe_map = map->AsElementsKind(expected_kind); |
| 1498 if (!maybe_map->To(&map)) return maybe_map; | 1486 if (!maybe_map->To(&map)) return maybe_map; |
| 1499 } | 1487 } |
| 1500 int total_size = | 1488 int total_size = |
| 1501 map->NumberOfOwnDescriptors() + map->unused_property_fields(); | 1489 map->NumberOfOwnDescriptors() + map->unused_property_fields(); |
| 1502 int out_of_object = total_size - map->inobject_properties(); | 1490 int out_of_object = total_size - map->inobject_properties(); |
| 1503 if (out_of_object != properties()->length()) { | 1491 if (out_of_object != properties()->length()) { |
| 1504 FixedArray* new_properties; | 1492 FixedArray* new_properties; |
| 1505 MaybeObject* maybe_properties = properties()->CopySize(out_of_object); | 1493 MaybeObject* maybe_properties = properties()->CopySize(out_of_object); |
| 1506 if (!maybe_properties->To(&new_properties)) return maybe_properties; | 1494 if (!maybe_properties->To(&new_properties)) return maybe_properties; |
| 1507 set_properties(new_properties); | 1495 set_properties(new_properties); |
| 1508 } | 1496 } |
| 1509 set_map(map); | 1497 set_map(map); |
| 1510 return this; | 1498 return this; |
| 1511 } | 1499 } |
| 1512 | 1500 |
| 1513 | 1501 |
| 1502 MaybeObject* JSObject::MigrateInstance() { |
| 1503 // Converting any field to the most specific type will cause the |
| 1504 // GeneralizeFieldRepresentation algorithm to create the most general existing |
| 1505 // transition that matches the object. This achieves what is needed. |
| 1506 return GeneralizeFieldRepresentation(0, Representation::Smi()); |
| 1507 } |
| 1508 |
| 1509 |
| 1514 Handle<String> JSObject::ExpectedTransitionKey(Handle<Map> map) { | 1510 Handle<String> JSObject::ExpectedTransitionKey(Handle<Map> map) { |
| 1515 AssertNoAllocation no_gc; | 1511 AssertNoAllocation no_gc; |
| 1516 if (!map->HasTransitionArray()) return Handle<String>::null(); | 1512 if (!map->HasTransitionArray()) return Handle<String>::null(); |
| 1517 TransitionArray* transitions = map->transitions(); | 1513 TransitionArray* transitions = map->transitions(); |
| 1518 if (!transitions->IsSimpleTransition()) return Handle<String>::null(); | 1514 if (!transitions->IsSimpleTransition()) return Handle<String>::null(); |
| 1519 int transition = TransitionArray::kSimpleTransitionIndex; | 1515 int transition = TransitionArray::kSimpleTransitionIndex; |
| 1520 PropertyDetails details = transitions->GetTargetDetails(transition); | 1516 PropertyDetails details = transitions->GetTargetDetails(transition); |
| 1521 Name* name = transitions->GetKey(transition); | 1517 Name* name = transitions->GetKey(transition); |
| 1522 if (details.type() != FIELD) return Handle<String>::null(); | 1518 if (details.type() != FIELD) return Handle<String>::null(); |
| 1523 if (details.attributes() != NONE) return Handle<String>::null(); | 1519 if (details.attributes() != NONE) return Handle<String>::null(); |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 return GetKey(GetSortedKeyIndex(descriptor_number)); | 2228 return GetKey(GetSortedKeyIndex(descriptor_number)); |
| 2233 } | 2229 } |
| 2234 | 2230 |
| 2235 | 2231 |
| 2236 void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) { | 2232 void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) { |
| 2237 PropertyDetails details = GetDetails(descriptor_index); | 2233 PropertyDetails details = GetDetails(descriptor_index); |
| 2238 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi()); | 2234 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi()); |
| 2239 } | 2235 } |
| 2240 | 2236 |
| 2241 | 2237 |
| 2238 void DescriptorArray::SetRepresentation(int descriptor_index, |
| 2239 Representation representation) { |
| 2240 ASSERT(!representation.IsNone()); |
| 2241 PropertyDetails details = GetDetails(descriptor_index); |
| 2242 set(ToDetailsIndex(descriptor_index), |
| 2243 details.set_representation(representation).AsSmi()); |
| 2244 } |
| 2245 |
| 2246 |
| 2247 void DescriptorArray::InitializeRepresentations(Representation representation) { |
| 2248 int length = number_of_descriptors(); |
| 2249 for (int i = 0; i < length; i++) { |
| 2250 PropertyDetails details = GetDetails(i); |
| 2251 set(ToDetailsIndex(i), details.set_representation(representation).AsSmi()); |
| 2252 } |
| 2253 } |
| 2254 |
| 2255 |
| 2242 Object** DescriptorArray::GetValueSlot(int descriptor_number) { | 2256 Object** DescriptorArray::GetValueSlot(int descriptor_number) { |
| 2243 ASSERT(descriptor_number < number_of_descriptors()); | 2257 ASSERT(descriptor_number < number_of_descriptors()); |
| 2244 return HeapObject::RawField( | 2258 return HeapObject::RawField( |
| 2245 reinterpret_cast<HeapObject*>(this), | 2259 reinterpret_cast<HeapObject*>(this), |
| 2246 OffsetOfElementAt(ToValueIndex(descriptor_number))); | 2260 OffsetOfElementAt(ToValueIndex(descriptor_number))); |
| 2247 } | 2261 } |
| 2248 | 2262 |
| 2249 | 2263 |
| 2250 Object* DescriptorArray::GetValue(int descriptor_number) { | 2264 Object* DescriptorArray::GetValue(int descriptor_number) { |
| 2251 ASSERT(descriptor_number < number_of_descriptors()); | 2265 ASSERT(descriptor_number < number_of_descriptors()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2297 | 2311 |
| 2298 void DescriptorArray::Set(int descriptor_number, | 2312 void DescriptorArray::Set(int descriptor_number, |
| 2299 Descriptor* desc, | 2313 Descriptor* desc, |
| 2300 const WhitenessWitness&) { | 2314 const WhitenessWitness&) { |
| 2301 // Range check. | 2315 // Range check. |
| 2302 ASSERT(descriptor_number < number_of_descriptors()); | 2316 ASSERT(descriptor_number < number_of_descriptors()); |
| 2303 ASSERT(desc->GetDetails().descriptor_index() <= | 2317 ASSERT(desc->GetDetails().descriptor_index() <= |
| 2304 number_of_descriptors()); | 2318 number_of_descriptors()); |
| 2305 ASSERT(desc->GetDetails().descriptor_index() > 0); | 2319 ASSERT(desc->GetDetails().descriptor_index() > 0); |
| 2306 | 2320 |
| 2321 ASSERT(!desc->GetDetails().representation().IsNone()); |
| 2307 NoIncrementalWriteBarrierSet(this, | 2322 NoIncrementalWriteBarrierSet(this, |
| 2308 ToKeyIndex(descriptor_number), | 2323 ToKeyIndex(descriptor_number), |
| 2309 desc->GetKey()); | 2324 desc->GetKey()); |
| 2310 NoIncrementalWriteBarrierSet(this, | 2325 NoIncrementalWriteBarrierSet(this, |
| 2311 ToValueIndex(descriptor_number), | 2326 ToValueIndex(descriptor_number), |
| 2312 desc->GetValue()); | 2327 desc->GetValue()); |
| 2313 NoIncrementalWriteBarrierSet(this, | 2328 NoIncrementalWriteBarrierSet(this, |
| 2314 ToDetailsIndex(descriptor_number), | 2329 ToDetailsIndex(descriptor_number), |
| 2315 desc->GetDetails().AsSmi()); | 2330 desc->GetDetails().AsSmi()); |
| 2316 } | 2331 } |
| 2317 | 2332 |
| 2318 | 2333 |
| 2319 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { | 2334 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { |
| 2320 // Range check. | 2335 // Range check. |
| 2321 ASSERT(descriptor_number < number_of_descriptors()); | 2336 ASSERT(descriptor_number < number_of_descriptors()); |
| 2322 ASSERT(desc->GetDetails().descriptor_index() <= | 2337 ASSERT(desc->GetDetails().descriptor_index() <= |
| 2323 number_of_descriptors()); | 2338 number_of_descriptors()); |
| 2324 ASSERT(desc->GetDetails().descriptor_index() > 0); | 2339 ASSERT(desc->GetDetails().descriptor_index() > 0); |
| 2340 ASSERT(!desc->GetDetails().representation().IsNone()); |
| 2325 | 2341 |
| 2326 set(ToKeyIndex(descriptor_number), desc->GetKey()); | 2342 set(ToKeyIndex(descriptor_number), desc->GetKey()); |
| 2327 set(ToValueIndex(descriptor_number), desc->GetValue()); | 2343 set(ToValueIndex(descriptor_number), desc->GetValue()); |
| 2328 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi()); | 2344 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi()); |
| 2329 } | 2345 } |
| 2330 | 2346 |
| 2331 | 2347 |
| 2332 void DescriptorArray::Append(Descriptor* desc, | 2348 void DescriptorArray::Append(Descriptor* desc, |
| 2333 const WhitenessWitness& witness) { | 2349 const WhitenessWitness& witness) { |
| 2334 int descriptor_number = number_of_descriptors(); | 2350 int descriptor_number = number_of_descriptors(); |
| (...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3528 has_slow_elements_kind() || has_external_array_elements()); | 3544 has_slow_elements_kind() || has_external_array_elements()); |
| 3529 set_bit_field3(IsObserved::update(bit_field3(), is_observed)); | 3545 set_bit_field3(IsObserved::update(bit_field3(), is_observed)); |
| 3530 } | 3546 } |
| 3531 | 3547 |
| 3532 | 3548 |
| 3533 bool Map::is_observed() { | 3549 bool Map::is_observed() { |
| 3534 return IsObserved::decode(bit_field3()); | 3550 return IsObserved::decode(bit_field3()); |
| 3535 } | 3551 } |
| 3536 | 3552 |
| 3537 | 3553 |
| 3554 void Map::deprecate() { |
| 3555 set_bit_field3(Deprecated::update(bit_field3(), true)); |
| 3556 } |
| 3557 |
| 3558 |
| 3559 bool Map::is_deprecated() { |
| 3560 if (!FLAG_track_fields) return false; |
| 3561 return Deprecated::decode(bit_field3()); |
| 3562 } |
| 3563 |
| 3564 |
| 3565 bool Map::CanBeDeprecated() { |
| 3566 int descriptor = LastAdded(); |
| 3567 for (int i = 0; i <= descriptor; i++) { |
| 3568 PropertyDetails details = instance_descriptors()->GetDetails(i); |
| 3569 if (FLAG_track_fields && details.representation().IsSmi()) { |
| 3570 return true; |
| 3571 } |
| 3572 if (FLAG_track_double_fields && details.representation().IsDouble()) { |
| 3573 return true; |
| 3574 } |
| 3575 } |
| 3576 return false; |
| 3577 } |
| 3578 |
| 3579 |
| 3538 void Map::NotifyLeafMapLayoutChange() { | 3580 void Map::NotifyLeafMapLayoutChange() { |
| 3539 dependent_code()->DeoptimizeDependentCodeGroup( | 3581 dependent_code()->DeoptimizeDependentCodeGroup( |
| 3540 GetIsolate(), | 3582 GetIsolate(), |
| 3541 DependentCode::kPrototypeCheckGroup); | 3583 DependentCode::kPrototypeCheckGroup); |
| 3542 } | 3584 } |
| 3543 | 3585 |
| 3544 | 3586 |
| 3545 bool Map::CanOmitPrototypeChecks() { | 3587 bool Map::CanOmitPrototypeChecks() { |
| 3546 return !HasTransitionArray() && !is_dictionary_map() && | 3588 return !HasTransitionArray() && !is_dictionary_map() && |
| 3547 FLAG_omit_prototype_checks_for_leaf_maps; | 3589 FLAG_omit_prototype_checks_for_leaf_maps; |
| (...skipping 2571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6119 #undef WRITE_UINT32_FIELD | 6161 #undef WRITE_UINT32_FIELD |
| 6120 #undef READ_SHORT_FIELD | 6162 #undef READ_SHORT_FIELD |
| 6121 #undef WRITE_SHORT_FIELD | 6163 #undef WRITE_SHORT_FIELD |
| 6122 #undef READ_BYTE_FIELD | 6164 #undef READ_BYTE_FIELD |
| 6123 #undef WRITE_BYTE_FIELD | 6165 #undef WRITE_BYTE_FIELD |
| 6124 | 6166 |
| 6125 | 6167 |
| 6126 } } // namespace v8::internal | 6168 } } // namespace v8::internal |
| 6127 | 6169 |
| 6128 #endif // V8_OBJECTS_INL_H_ | 6170 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |