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
+3 -3
View File
@@ -1804,7 +1804,7 @@ opfunc_func_decl_1 (OPCODE opdata, /**< operation data */
&arg_name_string_p, &arg_name_string_p,
1); 1);
ecma_free_string (arg_name_string_p); ecma_deref_ecma_string (arg_name_string_p);
return ret_value; return ret_value;
} /* opfunc_func_decl_1 */ } /* opfunc_func_decl_1 */
@@ -1837,8 +1837,8 @@ opfunc_func_decl_2 (OPCODE opdata, /**< operation data */
arg_names_strings, arg_names_strings,
2); 2);
ecma_free_string (arg_names_strings[0]); ecma_deref_ecma_string (arg_names_strings[0]);
ecma_free_string (arg_names_strings[1]); ecma_deref_ecma_string (arg_names_strings[1]);
return ret_value; return ret_value;
} /* opfunc_func_decl_2 */ } /* opfunc_func_decl_2 */
+10 -3
View File
@@ -517,10 +517,11 @@ typedef struct
*/ */
typedef enum typedef enum
{ {
ECMA_STRING_CONTAINER_HEAP, /**< actual data is on the heap ECMA_STRING_CONTAINER_HEAP_CHUNKS, /**< actual data is on the heap
in a ecma_collection_chunk_t chain */ in a ecma_collection_chunk_t chain */
ECMA_STRING_CONTAINER_LIT_TABLE, /**< actual data is in literal table */ 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; } ecma_string_container_t;
FIXME (Move to library that should define the type (libserializer /* ? */)) 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) */ /** Where the string's data is placed (ecma_string_container_t) */
unsigned int container : 2; unsigned int container : 2;
/** Flag indicating whether the length field is valid */
unsigned int is_length_valid : 1;
/** String's length */ /** String's length */
ecma_length_t length; ecma_length_t length;
@@ -554,6 +558,9 @@ typedef struct
/** Compressed pointer to an ecma_collection_chunk_t */ /** Compressed pointer to an ecma_collection_chunk_t */
unsigned int chunk_cp : ECMA_POINTER_FIELD_WIDTH; 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 */ /** Actual data if placed locally in the descriptor */
ecma_char_t chars[ sizeof (uint64_t) - sizeof (uint32_t) ]; ecma_char_t chars[ sizeof (uint64_t) - sizeof (uint32_t) ];
} u; } u;
+66 -28
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 (); ecma_string_t* string_desc_p = ecma_alloc_string ();
string_desc_p->refs = 1; string_desc_p->refs = 1;
string_desc_p->length = length; string_desc_p->length = length;
string_desc_p->is_length_valid = true;
if (bytes_needed_for_current_string <= bytes_for_chars_in_string_descriptor) 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; 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; 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; return string_desc_p;
} /* ecma_new_ecma_string */ } /* 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 * Decrease reference counter and deallocate ecma-string if
* after that the counter the counter becomes zero. * after that the counter the counter becomes zero.
*/ */
void 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 != NULL);
JERRY_ASSERT (string_p->refs != 0); JERRY_ASSERT (string_p->refs != 0);
@@ -107,7 +125,7 @@ ecma_free_string (ecma_string_t *string_p) /**< ecma-string */
return; 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); 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_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. * 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; 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); 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; break;
} }
case ECMA_STRING_CONTAINER_LIT_TABLE: case ECMA_STRING_CONTAINER_LIT_TABLE:
case ECMA_STRING_CONTAINER_HEAP_NUMBER:
{ {
JERRY_UNIMPLEMENTED(); 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; return (ssize_t) required_buffer_size;
} /* ecma_string_to_zt_string */ } /* 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 * 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(); 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) && string2_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR)
{ {
const ecma_string_t *tmp_string_p = string1_p; const ecma_string_t *tmp_string_p = string1_p;
string1_p = string2_p; string1_p = string2_p;
string2_p = tmp_string_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; 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; 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) if (cur_char_buffer_1_iter_p == cur_char_buffer_1_end_p)
{ {
JERRY_ASSERT (string1_p->container == ECMA_STRING_CONTAINER_HEAP JERRY_ASSERT (string1_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS
&& string2_p->container == ECMA_STRING_CONTAINER_HEAP); && string2_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS);
JERRY_ASSERT (cur_char_buffer_2_iter_p == cur_char_buffer_2_end_p); 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); 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_cur = ecma_string_p->u.chars;
current_chunk_chars_end = current_chunk_chars_cur + sizeof (ecma_string_p->u.chars) / sizeof (ecma_char_t); 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); string_chunk_p = ECMA_GET_POINTER (ecma_string_p->u.chunk_cp);
current_chunk_chars_cur = string_chunk_p->data; 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) 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 */ /* switching to next chunk */
string_chunk_p = ECMA_GET_POINTER (string_chunk_p->next_chunk_cp); string_chunk_p = ECMA_GET_POINTER (string_chunk_p->next_chunk_cp);
+1 -1
View File
@@ -271,7 +271,7 @@ ecma_free_value (ecma_value_t value, /**< value description */
case ECMA_TYPE_STRING: case ECMA_TYPE_STRING:
{ {
ecma_string_t *string_p = ECMA_GET_POINTER(value.value); ecma_string_t *string_p = ECMA_GET_POINTER(value.value);
ecma_free_string (string_p); ecma_deref_ecma_string (string_p);
break; break;
} }
+2 -2
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); 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_free_value (property_p->u.named_data_property.value, false);
ecma_dealloc_property (property_p); 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); 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_dealloc_property (property_p);
} /* ecma_free_named_accessor_property */ } /* ecma_free_named_accessor_property */
+3 -2
View File
@@ -87,11 +87,12 @@ extern bool ecma_is_empty_completion_value (ecma_completion_value_t value);
/* ecma-helpers-string.c */ /* ecma-helpers-string.c */
extern ecma_string_t* ecma_new_ecma_string (const ecma_char_t *string_p); 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, extern ssize_t ecma_string_to_zt_string (ecma_string_t *string_desc_p,
ecma_char_t *buffer_p, ecma_char_t *buffer_p,
size_t buffer_size); 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 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, extern bool ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p,
const ecma_string_t *ecma_string_p); const ecma_string_t *ecma_string_p);