/** * Invalidate LCache entries associated with given object and property name / property * * Note: * Either property name argument or property argument should be NULL, * and another should be non-NULL. * In case property name argument is NULL, property's name is taken * from property's description. */ void ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */ ecma_string_t *prop_name_p, /**< property's name (See also: Note) */ ecma_property_t *prop_p) /**< property (See also: Note) */ { JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (prop_name_p != NULL); #ifndef CONFIG_ECMA_LCACHE_DISABLE if (prop_p != NULL) { JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA || ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); bool is_cached = ecma_is_property_lcached (prop_p); if (!is_cached) { return; } ecma_set_property_lcached (prop_p, false); } unsigned int object_cp; ECMA_SET_NON_NULL_POINTER (object_cp, object_p); lit_string_hash_t hash_key = ecma_string_hash (prop_name_p); /* Property's name has was computed. * Given (object, property name) pair should be in the row corresponding to computed hash. */ ecma_lcache_invalidate_row_for_object_property_pair (hash_key, object_cp, prop_p); #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ } /* ecma_lcache_invalidate */
/** * Invalidate specified LCache entry */ static inline void __attr_always_inline___ ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to invalidate */ { JERRY_ASSERT (entry_p != NULL); JERRY_ASSERT (entry_p->object_cp != ECMA_NULL_POINTER); JERRY_ASSERT (entry_p->prop_p != NULL); entry_p->object_cp = ECMA_NULL_POINTER; ecma_set_property_lcached (entry_p->prop_p, false); } /* ecma_lcache_invalidate_entry */
/** * Insert an entry into LCache */ void ecma_lcache_insert (ecma_object_t *object_p, /**< object */ jmem_cpointer_t name_cp, /**< property name */ ecma_property_t *prop_p) /**< property */ { JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (prop_p != NULL && !ecma_is_property_lcached (prop_p)); JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA || ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); #ifndef CONFIG_ECMA_LCACHE_DISABLE jmem_cpointer_t object_cp; ECMA_SET_NON_NULL_POINTER (object_cp, object_p); lit_string_hash_t name_hash = ecma_string_get_property_name_hash (*prop_p, name_cp); size_t row_index = ecma_lcache_row_index (object_cp, name_hash); ecma_lcache_hash_entry_t *entries_p = JERRY_HASH_TABLE_CONTEXT (table)[row_index]; int32_t entry_index; for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++) { if (entries_p[entry_index].object_cp == ECMA_NULL_POINTER) { break; } } if (entry_index == ECMA_LCACHE_HASH_ROW_LENGTH) { /* Invalidate the last entry. */ ecma_lcache_invalidate_entry (entries_p + ECMA_LCACHE_HASH_ROW_LENGTH - 1); /* Shift other entries towards the end. */ for (uint32_t i = ECMA_LCACHE_HASH_ROW_LENGTH - 1; i > 0; i--) { entries_p[i] = entries_p[i - 1]; } entry_index = 0; } ecma_lcache_hash_entry_t *entry_p = entries_p + entry_index; ECMA_SET_NON_NULL_POINTER (entry_p->object_cp, object_p); entry_p->prop_name_cp = name_cp; entry_p->prop_p = prop_p; ecma_set_property_lcached (entry_p->prop_p, true); #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ } /* ecma_lcache_insert */
/** * Invalidate specified LCache entry */ static void ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to invalidate */ { JERRY_ASSERT (entry_p != NULL); JERRY_ASSERT (entry_p->object_cp != ECMA_NULL_POINTER); ecma_deref_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, entry_p->object_cp)); entry_p->object_cp = ECMA_NULL_POINTER; ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, entry_p->prop_name_cp)); if (entry_p->prop_p != NULL) { ecma_set_property_lcached (entry_p->prop_p, false); } } /* ecma_lcache_invalidate_entry */
/** * Insert an entry into LCache */ void ecma_lcache_insert (ecma_object_t *object_p, /**< object */ ecma_string_t *prop_name_p, /**< property's name */ ecma_property_t *prop_p) /**< pointer to associated property or NULL * (NULL indicates that the object doesn't have property * with the name specified) */ { JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (prop_name_p != NULL); #ifndef CONFIG_ECMA_LCACHE_DISABLE prop_name_p = ecma_copy_or_ref_ecma_string (prop_name_p); lit_string_hash_t hash_key = ecma_string_hash (prop_name_p); if (prop_p != NULL) { if (unlikely (ecma_is_property_lcached (prop_p))) { int32_t entry_index; for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++) { if (ecma_lcache_hash_table[hash_key][entry_index].object_cp != ECMA_NULL_POINTER && ecma_lcache_hash_table[hash_key][entry_index].prop_p == prop_p) { #ifndef JERRY_NDEBUG ecma_object_t *obj_in_entry_p; obj_in_entry_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, ecma_lcache_hash_table[hash_key][entry_index].object_cp); JERRY_ASSERT (obj_in_entry_p == object_p); #endif /* !JERRY_NDEBUG */ break; } } JERRY_ASSERT (entry_index != ECMA_LCACHE_HASH_ROW_LENGTH); ecma_lcache_invalidate_entry (&ecma_lcache_hash_table[hash_key][entry_index]); } JERRY_ASSERT (!ecma_is_property_lcached (prop_p)); ecma_set_property_lcached (prop_p, true); } int32_t entry_index; for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++) { if (ecma_lcache_hash_table[hash_key][entry_index].object_cp == ECMA_NULL_POINTER) { break; } } if (entry_index == ECMA_LCACHE_HASH_ROW_LENGTH) { /* No empty entry was found, invalidating the whole row */ for (uint32_t i = 0; i < ECMA_LCACHE_HASH_ROW_LENGTH; i++) { ecma_lcache_invalidate_entry (&ecma_lcache_hash_table[hash_key][i]); } entry_index = 0; } ecma_ref_object (object_p); ECMA_SET_NON_NULL_POINTER (ecma_lcache_hash_table[ hash_key ][ entry_index ].object_cp, object_p); ECMA_SET_NON_NULL_POINTER (ecma_lcache_hash_table[ hash_key ][ entry_index ].prop_name_cp, prop_name_p); ecma_lcache_hash_table[ hash_key ][ entry_index ].prop_p = prop_p; #else /* CONFIG_ECMA_LCACHE_DISABLE */ (void) prop_p; #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ } /* ecma_lcache_insert */