From 1ab3eaa389a3f2158a0738d511c7c30b78581fb6 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Fri, 8 Aug 2014 15:22:05 +0400 Subject: [PATCH] Optimizing ecma_get_pointer/ecma_set_pointer, introducing ecma_set_non_null_pointer. loop_arithmetics_1kk.js benchmark: 3.450 -> 3.025. --- src/libecmaobjects/ecma-helpers-value.c | 2 +- src/libecmaobjects/ecma-helpers.c | 46 ++++++++++++------------- src/libecmaobjects/ecma-helpers.h | 18 ++++++++-- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/libecmaobjects/ecma-helpers-value.c b/src/libecmaobjects/ecma-helpers-value.c index 0c222d170..dd4550475 100644 --- a/src/libecmaobjects/ecma-helpers-value.c +++ b/src/libecmaobjects/ecma-helpers-value.c @@ -194,7 +194,7 @@ ecma_copy_value( const ecma_value_t value, /**< ecma-value */ *number_copy_p = *num_p; value_copy = (ecma_value_t) { .value_type = ECMA_TYPE_NUMBER }; - ecma_set_pointer( value_copy.value, number_copy_p); + ecma_set_non_null_pointer( value_copy.value, number_copy_p); break; } diff --git a/src/libecmaobjects/ecma-helpers.c b/src/libecmaobjects/ecma-helpers.c index 75e099169..95752f893 100644 --- a/src/libecmaobjects/ecma-helpers.c +++ b/src/libecmaobjects/ecma-helpers.c @@ -32,10 +32,7 @@ uintptr_t ecma_compress_pointer(void *pointer) /**< pointer to compress */ { - if ( pointer == NULL ) - { - return ECMA_NULL_POINTER; - } + JERRY_ASSERT( pointer != NULL ); uintptr_t int_ptr = (uintptr_t) pointer; @@ -55,10 +52,7 @@ ecma_compress_pointer(void *pointer) /**< pointer to compress */ void* ecma_decompress_pointer(uintptr_t compressed_pointer) /**< pointer to decompress */ { - if ( compressed_pointer == ECMA_NULL_POINTER ) - { - return NULL; - } + JERRY_ASSERT( compressed_pointer != ECMA_NULL_POINTER ); uintptr_t int_ptr = compressed_pointer; @@ -173,8 +167,9 @@ ecma_create_internal_property(ecma_object_t *object_p, /**< the object */ new_property_p->type = ECMA_PROPERTY_INTERNAL; - ecma_set_pointer( new_property_p->next_property_p, ecma_get_pointer( object_p->properties_p)); - ecma_set_pointer( object_p->properties_p, new_property_p); + ecma_property_t *list_head_p = ecma_get_pointer( object_p->properties_p); + ecma_set_pointer( new_property_p->next_property_p, list_head_p); + ecma_set_non_null_pointer( object_p->properties_p, new_property_p); new_property_p->u.internal_property.type = property_id; new_property_p->u.internal_property.value = ECMA_NULL_POINTER; @@ -247,22 +242,24 @@ ecma_create_named_data_property(ecma_object_t *obj_p, /**< object */ { JERRY_ASSERT( obj_p != NULL && name_p != NULL ); - ecma_property_t *prop = ecma_alloc_property(); + ecma_property_t *prop_p = ecma_alloc_property(); - prop->type = ECMA_PROPERTY_NAMEDDATA; + prop_p->type = ECMA_PROPERTY_NAMEDDATA; - ecma_set_pointer( prop->u.named_data_property.name_p, ecma_new_ecma_string( name_p)); + ecma_set_non_null_pointer( prop_p->u.named_data_property.name_p, ecma_new_ecma_string( name_p)); - prop->u.named_data_property.writable = writable; - prop->u.named_data_property.enumerable = enumerable; - prop->u.named_data_property.configurable = configurable; + prop_p->u.named_data_property.writable = writable; + prop_p->u.named_data_property.enumerable = enumerable; + prop_p->u.named_data_property.configurable = configurable; - prop->u.named_data_property.value = ecma_make_simple_value( ECMA_SIMPLE_VALUE_UNDEFINED); + prop_p->u.named_data_property.value = ecma_make_simple_value( ECMA_SIMPLE_VALUE_UNDEFINED); - ecma_set_pointer( prop->next_property_p, ecma_get_pointer( obj_p->properties_p)); - ecma_set_pointer( obj_p->properties_p, prop); + ecma_property_t *list_head_p = ecma_get_pointer( obj_p->properties_p); - return prop; + ecma_set_pointer( prop_p->next_property_p, list_head_p); + ecma_set_non_null_pointer( obj_p->properties_p, prop_p); + + return prop_p; } /* ecma_create_named_data_property */ /** @@ -284,7 +281,7 @@ ecma_create_named_accessor_property(ecma_object_t *obj_p, /**< object */ prop_p->type = ECMA_PROPERTY_NAMEDACCESSOR; - ecma_set_pointer( prop_p->u.named_accessor_property.name_p, ecma_new_ecma_string( name_p)); + ecma_set_non_null_pointer( prop_p->u.named_accessor_property.name_p, ecma_new_ecma_string( name_p)); ecma_set_pointer( prop_p->u.named_accessor_property.get_p, get_p); ecma_gc_update_may_ref_younger_object_flag_by_object( obj_p, get_p); @@ -295,8 +292,9 @@ ecma_create_named_accessor_property(ecma_object_t *obj_p, /**< object */ prop_p->u.named_accessor_property.enumerable = enumerable; prop_p->u.named_accessor_property.configurable = configurable; - ecma_set_pointer( prop_p->next_property_p, ecma_get_pointer( obj_p->properties_p)); - ecma_set_pointer( obj_p->properties_p, prop_p); + ecma_property_t *list_head_p = ecma_get_pointer( obj_p->properties_p); + ecma_set_pointer( prop_p->next_property_p, list_head_p); + ecma_set_non_null_pointer( obj_p->properties_p, prop_p); return prop_p; } /* ecma_create_named_accessor_property */ @@ -562,7 +560,7 @@ ecma_new_ecma_string(const ecma_char_t *string_p) /**< zero-terminated string of chars_left -= chars_to_copy; copy_pointer += chars_to_copy * sizeof (ecma_char_t); - ecma_set_pointer( *next_chunk_compressed_pointer_p, string_non_first_chunk_p); + ecma_set_non_null_pointer( *next_chunk_compressed_pointer_p, string_non_first_chunk_p); next_chunk_compressed_pointer_p = &string_non_first_chunk_p->next_chunk_p; } diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index c73399a07..13e105c72 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -32,14 +32,28 @@ extern void* ecma_decompress_pointer(uintptr_t compressed_pointer); * Get value of pointer from specified compressed pointer field. */ #define ecma_get_pointer( field) \ - ecma_decompress_pointer( field) + ( ( unlikely( field == ECMA_NULL_POINTER ) ) ? NULL : ecma_decompress_pointer( field) ) /** * Set value of compressed pointer field so that it will correspond * to specified non_compressed_pointer. */ #define ecma_set_pointer( field, non_compressed_pointer) \ - (field) = ecma_compress_pointer( non_compressed_pointer) & ( ( 1u << ECMA_POINTER_FIELD_WIDTH ) - 1) + do { \ + void *__temp_pointer = non_compressed_pointer; \ + non_compressed_pointer = __temp_pointer; \ + } \ + while(0); \ + (field) = ( unlikely ( ( non_compressed_pointer ) == NULL ) ? ECMA_NULL_POINTER \ + : ecma_compress_pointer( non_compressed_pointer) \ + & ( ( 1u << ECMA_POINTER_FIELD_WIDTH ) - 1) ) + +/** + * Set value of non-null compressed pointer field so that it will correspond + * to specified non_compressed_pointer. + */ +#define ecma_set_non_null_pointer( field, non_compressed_pointer) \ + (field) = ( ecma_compress_pointer( non_compressed_pointer) & ( ( 1u << ECMA_POINTER_FIELD_WIDTH ) - 1) ) /* ecma-helpers-value.c */ extern bool ecma_is_value_empty( ecma_value_t value);