Preparations to lazy conversion of Number to String: introducing ECMA_STRING_CONTAINER_HEAP_NUMBER container type for ecma_string_t.

This commit is contained in:
Ruben Ayrapetyan 2014-08-18 16:10:54 +04:00
parent 471bbd9fc4
commit bcddffbefb
6 changed files with 85 additions and 39 deletions

View File

@ -1804,7 +1804,7 @@ opfunc_func_decl_1 (OPCODE opdata, /**< operation data */
&arg_name_string_p,
1);
ecma_free_string (arg_name_string_p);
ecma_deref_ecma_string (arg_name_string_p);
return ret_value;
} /* opfunc_func_decl_1 */
@ -1837,8 +1837,8 @@ opfunc_func_decl_2 (OPCODE opdata, /**< operation data */
arg_names_strings,
2);
ecma_free_string (arg_names_strings[0]);
ecma_free_string (arg_names_strings[1]);
ecma_deref_ecma_string (arg_names_strings[0]);
ecma_deref_ecma_string (arg_names_strings[1]);
return ret_value;
} /* opfunc_func_decl_2 */

View File

@ -517,10 +517,11 @@ typedef struct
*/
typedef enum
{
ECMA_STRING_CONTAINER_HEAP, /**< actual data is on the heap
in a ecma_collection_chunk_t chain */
ECMA_STRING_CONTAINER_HEAP_CHUNKS, /**< actual data is on the heap
in a ecma_collection_chunk_t chain */
ECMA_STRING_CONTAINER_LIT_TABLE, /**< actual data is in literal table */
ECMA_STRING_CONTAINER_IN_DESCRIPTOR /**< actual data is locally in the string's descriptor */
ECMA_STRING_CONTAINER_IN_DESCRIPTOR, /**< actual data is locally in the string's descriptor */
ECMA_STRING_CONTAINER_HEAP_NUMBER /**< actual data is on the heap as a ecma_number_t */
} ecma_string_container_t;
FIXME (Move to library that should define the type (libserializer /* ? */))
@ -540,6 +541,9 @@ typedef struct
/** Where the string's data is placed (ecma_string_container_t) */
unsigned int container : 2;
/** Flag indicating whether the length field is valid */
unsigned int is_length_valid : 1;
/** String's length */
ecma_length_t length;
@ -554,6 +558,9 @@ typedef struct
/** Compressed pointer to an ecma_collection_chunk_t */
unsigned int chunk_cp : ECMA_POINTER_FIELD_WIDTH;
/** Compressed pointer to an ecma_number_t */
unsigned int number_cp : ECMA_POINTER_FIELD_WIDTH;
/** Actual data if placed locally in the descriptor */
ecma_char_t chars[ sizeof (uint64_t) - sizeof (uint32_t) ];
} u;

View File

@ -51,6 +51,7 @@ ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string *
ecma_string_t* string_desc_p = ecma_alloc_string ();
string_desc_p->refs = 1;
string_desc_p->length = length;
string_desc_p->is_length_valid = true;
if (bytes_needed_for_current_string <= bytes_for_chars_in_string_descriptor)
{
@ -60,7 +61,7 @@ ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string *
return string_desc_p;
}
string_desc_p->container = ECMA_STRING_CONTAINER_HEAP;
string_desc_p->container = ECMA_STRING_CONTAINER_HEAP_CHUNKS;
const ecma_char_t* src_p = string_p;
@ -90,12 +91,29 @@ ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string *
return string_desc_p;
} /* ecma_new_ecma_string */
/**
* Increase reference counter of ecma-string.
*
* @return pointer to same ecma-string descriptor with increased reference counter
*/
void
ecma_ref_ecma_string (ecma_string_t *string_desc_p) /**< string descriptor */
{
JERRY_ASSERT (string_desc_p != NULL);
JERRY_ASSERT (string_desc_p->refs > 0);
string_desc_p->refs++;
/* Check for overflow */
JERRY_ASSERT (string_desc_p->refs > 0);
} /* ecma_ref_ecma_string */
/**
* Decrease reference counter and deallocate ecma-string if
* after that the counter the counter becomes zero.
*/
void
ecma_free_string (ecma_string_t *string_p) /**< ecma-string */
ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
{
JERRY_ASSERT (string_p != NULL);
JERRY_ASSERT (string_p->refs != 0);
@ -107,7 +125,7 @@ ecma_free_string (ecma_string_t *string_p) /**< ecma-string */
return;
}
if (string_p->container == ECMA_STRING_CONTAINER_HEAP)
if (string_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS)
{
ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (string_p->u.chunk_cp);
@ -131,7 +149,43 @@ ecma_free_string (ecma_string_t *string_p) /**< ecma-string */
}
ecma_dealloc_string (string_p);
} /* ecma_free_string */
} /* ecma_deref_ecma_string */
/**
* Get length of the ecma-string
*
* @return length
*/
ecma_length_t
ecma_get_ecma_string_length (ecma_string_t *string_desc_p) /**< ecma-string descriptor */
{
switch ((ecma_string_container_t)string_desc_p->container)
{
case ECMA_STRING_CONTAINER_HEAP_CHUNKS:
case ECMA_STRING_CONTAINER_LIT_TABLE:
case ECMA_STRING_CONTAINER_IN_DESCRIPTOR:
{
JERRY_ASSERT (string_desc_p->is_length_valid);
return string_desc_p->length;
}
case ECMA_STRING_CONTAINER_HEAP_NUMBER:
{
if (string_desc_p->is_length_valid)
{
return string_desc_p->length;
}
else
{
/* calculate length */
JERRY_UNIMPLEMENTED();
}
}
}
JERRY_UNREACHABLE();
} /* ecma_get_ecma_string_length */
/**
* Copy ecma-string's contents to a buffer.
@ -171,7 +225,7 @@ ecma_string_to_zt_string (ecma_string_t *string_desc_p, /**< ecma-string descrip
break;
}
case ECMA_STRING_CONTAINER_HEAP:
case ECMA_STRING_CONTAINER_HEAP_CHUNKS:
{
ecma_collection_chunk_t *string_chunk_p = ECMA_GET_POINTER (string_desc_p->u.chunk_cp);
@ -193,6 +247,7 @@ ecma_string_to_zt_string (ecma_string_t *string_desc_p, /**< ecma-string descrip
break;
}
case ECMA_STRING_CONTAINER_LIT_TABLE:
case ECMA_STRING_CONTAINER_HEAP_NUMBER:
{
JERRY_UNIMPLEMENTED();
}
@ -203,23 +258,6 @@ ecma_string_to_zt_string (ecma_string_t *string_desc_p, /**< ecma-string descrip
return (ssize_t) required_buffer_size;
} /* ecma_string_to_zt_string */
/**
* Increase reference counter of ecma-string.
*
* @return pointer to same ecma-string descriptor with increased reference counter
*/
void
ecma_ref_ecma_string (ecma_string_t *string_desc_p) /**< string descriptor */
{
JERRY_ASSERT (string_desc_p != NULL);
JERRY_ASSERT (string_desc_p->refs > 0);
string_desc_p->refs++;
/* Check for overflow */
JERRY_ASSERT (string_desc_p->refs > 0);
} /* ecma_ref_ecma_string */
/**
* Compare ecma-string to ecma-string
*
@ -256,14 +294,14 @@ ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p, /* ecma
JERRY_UNIMPLEMENTED();
}
if (string1_p->container == ECMA_STRING_CONTAINER_HEAP
if (string1_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS
&& string2_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR)
{
const ecma_string_t *tmp_string_p = string1_p;
string1_p = string2_p;
string2_p = tmp_string_p;
}
JERRY_ASSERT (string2_p->container == ECMA_STRING_CONTAINER_HEAP);
JERRY_ASSERT (string2_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS);
ecma_collection_chunk_t *string1_chunk_p, *string2_chunk_p;
const ecma_char_t *cur_char_buffer_1_iter_p, *cur_char_buffer_2_iter_p;
@ -314,8 +352,8 @@ ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p, /* ecma
if (cur_char_buffer_1_iter_p == cur_char_buffer_1_end_p)
{
JERRY_ASSERT (string1_p->container == ECMA_STRING_CONTAINER_HEAP
&& string2_p->container == ECMA_STRING_CONTAINER_HEAP);
JERRY_ASSERT (string1_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS
&& string2_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS);
JERRY_ASSERT (cur_char_buffer_2_iter_p == cur_char_buffer_2_end_p);
string1_chunk_p = ECMA_GET_POINTER (string1_chunk_p->next_chunk_cp);
@ -373,7 +411,7 @@ ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p, /**< zero-te
current_chunk_chars_cur = ecma_string_p->u.chars;
current_chunk_chars_end = current_chunk_chars_cur + sizeof (ecma_string_p->u.chars) / sizeof (ecma_char_t);
}
else if (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP)
else if (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS)
{
string_chunk_p = ECMA_GET_POINTER (ecma_string_p->u.chunk_cp);
current_chunk_chars_cur = string_chunk_p->data;
@ -394,7 +432,7 @@ ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p, /**< zero-te
if (current_chunk_chars_cur == current_chunk_chars_end)
{
JERRY_ASSERT (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP);
JERRY_ASSERT (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS);
/* switching to next chunk */
string_chunk_p = ECMA_GET_POINTER (string_chunk_p->next_chunk_cp);

View File

@ -271,7 +271,7 @@ ecma_free_value (ecma_value_t value, /**< value description */
case ECMA_TYPE_STRING:
{
ecma_string_t *string_p = ECMA_GET_POINTER(value.value);
ecma_free_string (string_p);
ecma_deref_ecma_string (string_p);
break;
}

View File

@ -361,7 +361,7 @@ ecma_free_named_data_property (ecma_property_t *property_p) /**< the property */
{
JERRY_ASSERT(property_p->type == ECMA_PROPERTY_NAMEDDATA);
ecma_free_string (ECMA_GET_POINTER (property_p->u.named_data_property.name_p));
ecma_deref_ecma_string (ECMA_GET_POINTER (property_p->u.named_data_property.name_p));
ecma_free_value (property_p->u.named_data_property.value, false);
ecma_dealloc_property (property_p);
@ -375,7 +375,7 @@ ecma_free_named_accessor_property (ecma_property_t *property_p) /**< the propert
{
JERRY_ASSERT(property_p->type == ECMA_PROPERTY_NAMEDACCESSOR);
ecma_free_string (ECMA_GET_POINTER (property_p->u.named_accessor_property.name_p));
ecma_deref_ecma_string (ECMA_GET_POINTER (property_p->u.named_accessor_property.name_p));
ecma_dealloc_property (property_p);
} /* ecma_free_named_accessor_property */

View File

@ -87,11 +87,12 @@ extern bool ecma_is_empty_completion_value (ecma_completion_value_t value);
/* ecma-helpers-string.c */
extern ecma_string_t* ecma_new_ecma_string (const ecma_char_t *string_p);
extern void ecma_free_string (ecma_string_t *string_p);
extern void ecma_ref_ecma_string (ecma_string_t *string_desc_p);
extern void ecma_deref_ecma_string (ecma_string_t *string_p);
extern ecma_length_t ecma_get_ecma_string_length (ecma_string_t *string_desc_p);
extern ssize_t ecma_string_to_zt_string (ecma_string_t *string_desc_p,
ecma_char_t *buffer_p,
size_t buffer_size);
extern void ecma_ref_ecma_string (ecma_string_t *string_desc_p);
extern int32_t ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p, const ecma_char_t *string2_p);
extern bool ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p,
const ecma_string_t *ecma_string_p);