@@ -152,3 +152,176 @@ jsp_bc_finalize ()
152152 }
153153} /* jsp_bc_finalize */
154154
155+ /* *
156+ * Convert literal id (operand value of instruction) to compressed pointer to literal
157+ *
158+ * Bytecode is divided into blocks of fixed size and each block has independent encoding of variable names,
159+ * which are represented by 8 bit numbers - ids.
160+ * This function performs conversion from id to literal.
161+ *
162+ * @return compressed pointer to literal
163+ */
164+ lit_cpointer_t
165+ bc_get_literal_cp_by_uid (uint8_t id, /* *< literal idx */
166+ const bytecode_data_header_t *bytecode_data_p, /* *< pointer to bytecode */
167+ vm_instr_counter_t oc) /* *< position in the bytecode */
168+ {
169+ JERRY_ASSERT (bytecode_data_p);
170+
171+ lit_id_hash_table *lit_id_hash = null_hash;
172+ lit_id_hash = MEM_CP_GET_POINTER (lit_id_hash_table, bytecode_data_p->lit_id_hash_cp );
173+
174+ if (lit_id_hash == null_hash)
175+ {
176+ return INVALID_LITERAL;
177+ }
178+
179+ return lit_id_hash_table_lookup (lit_id_hash, id, oc);
180+ } /* serializer_get_literal_cp_by_uid */
181+
182+ #ifdef JERRY_ENABLE_SNAPSHOT
183+ /* *
184+ * Dump byte-code and idx-to-literal map to snapshot
185+ *
186+ * @return true, upon success (i.e. buffer size is enough),
187+ * false - otherwise.
188+ */
189+ bool
190+ bc_save_bytecode_with_idx_map (uint8_t *buffer_p, /* *< buffer to dump to */
191+ size_t buffer_size, /* *< buffer size */
192+ size_t *in_out_buffer_offset_p, /* *< in-out: buffer write offset */
193+ const bytecode_data_header_t *bytecode_data_p, /* *< byte-code data */
194+ const lit_mem_to_snapshot_id_map_entry_t *lit_map_p, /* *< map from literal
195+ * identifiers in
196+ * literal storage
197+ * to literal offsets
198+ * in snapshot */
199+ uint32_t literals_num, /* *< literals number */
200+ uint32_t *out_bytecode_size_p, /* *< out: size of dumped instructions array */
201+ uint32_t *out_idx_to_lit_map_size_p) /* *< out: side of dumped
202+ * idx to literals map */
203+ {
204+ JERRY_ASSERT (bytecode_data_p->next_header_cp == MEM_CP_NULL);
205+
206+ vm_instr_counter_t instrs_num = bytecode_data_p->instrs_count ;
207+
208+ const size_t instrs_array_size = sizeof (vm_instr_t ) * instrs_num;
209+ if (*in_out_buffer_offset_p + instrs_array_size > buffer_size)
210+ {
211+ return false ;
212+ }
213+ memcpy (buffer_p + *in_out_buffer_offset_p, bytecode_data_p->instrs_p , instrs_array_size);
214+ *in_out_buffer_offset_p += instrs_array_size;
215+
216+ *out_bytecode_size_p = (uint32_t ) (sizeof (vm_instr_t ) * instrs_num);
217+
218+ lit_id_hash_table *lit_id_hash_p = MEM_CP_GET_POINTER (lit_id_hash_table, bytecode_data_p->lit_id_hash_cp );
219+ uint32_t idx_to_lit_map_size = lit_id_hash_table_dump_for_snapshot (buffer_p,
220+ buffer_size,
221+ in_out_buffer_offset_p,
222+ lit_id_hash_p,
223+ lit_map_p,
224+ literals_num,
225+ instrs_num);
226+
227+ if (idx_to_lit_map_size == 0 )
228+ {
229+ return false ;
230+ }
231+ else
232+ {
233+ *out_idx_to_lit_map_size_p = idx_to_lit_map_size;
234+
235+ return true ;
236+ }
237+ } /* serializer_dump_bytecode_with_idx_map */
238+
239+ /* *
240+ * Register bytecode and idx map from snapshot
241+ *
242+ * NOTE:
243+ * If is_copy flag is set, bytecode is copied from snapshot, else bytecode is referenced directly
244+ * from snapshot
245+ *
246+ * @return pointer to byte-code header, upon success,
247+ * NULL - upon failure (i.e., in case snapshot format is not valid)
248+ */
249+ const bytecode_data_header_t *
250+ bc_load_bytecode_with_idx_map (const uint8_t *bytecode_and_idx_map_p, /* *< buffer with instructions array
251+ * and idx to literals map from
252+ * snapshot */
253+ uint32_t bytecode_size, /* *< size of instructions array */
254+ uint32_t idx_to_lit_map_size, /* *< size of the idx to literals map */
255+ const lit_mem_to_snapshot_id_map_entry_t *lit_map_p, /* *< map of in-snapshot
256+ * literal offsets
257+ * to literal identifiers,
258+ * created in literal
259+ * storage */
260+ uint32_t literals_num, /* *< number of literals */
261+ bool is_copy) /* * flag, indicating whether the passed in-snapshot data
262+ * should be copied to engine's memory (true),
263+ * or it can be referenced until engine is stopped
264+ * (i.e. until call to jerry_cleanup) */
265+ {
266+ const uint8_t *idx_to_lit_map_p = bytecode_and_idx_map_p + bytecode_size;
267+
268+ size_t instructions_number = bytecode_size / sizeof (vm_instr_t );
269+ size_t blocks_count = JERRY_ALIGNUP (instructions_number, BLOCK_SIZE) / BLOCK_SIZE;
270+
271+ uint32_t idx_num_total;
272+ size_t idx_to_lit_map_offset = 0 ;
273+ if (!jrt_read_from_buffer_by_offset (idx_to_lit_map_p,
274+ idx_to_lit_map_size,
275+ &idx_to_lit_map_offset,
276+ &idx_num_total))
277+ {
278+ return NULL ;
279+ }
280+
281+ const size_t bytecode_alloc_size = JERRY_ALIGNUP (bytecode_size, MEM_ALIGNMENT);
282+ const size_t hash_table_size = lit_id_hash_table_get_size_for_table (idx_num_total, blocks_count);
283+ const size_t header_and_hash_table_size = JERRY_ALIGNUP (sizeof (bytecode_data_header_t ) + hash_table_size,
284+ MEM_ALIGNMENT);
285+ const size_t alloc_size = header_and_hash_table_size + (is_copy ? bytecode_alloc_size : 0 );
286+
287+ uint8_t *buffer_p = (uint8_t *) mem_heap_alloc_block (alloc_size, MEM_HEAP_ALLOC_LONG_TERM);
288+ bytecode_data_header_t *header_p = (bytecode_data_header_t *) buffer_p;
289+
290+ vm_instr_t *instrs_p;
291+ vm_instr_t *snapshot_instrs_p = (vm_instr_t *) bytecode_and_idx_map_p;
292+ if (is_copy)
293+ {
294+ instrs_p = (vm_instr_t *) (buffer_p + header_and_hash_table_size);
295+ memcpy (instrs_p, snapshot_instrs_p, bytecode_size);
296+ }
297+ else
298+ {
299+ instrs_p = snapshot_instrs_p;
300+ }
301+
302+ uint8_t *lit_id_hash_table_buffer_p = buffer_p + sizeof (bytecode_data_header_t );
303+ if (lit_id_hash_table_load_from_snapshot (blocks_count,
304+ idx_num_total,
305+ idx_to_lit_map_p + idx_to_lit_map_offset,
306+ idx_to_lit_map_size - idx_to_lit_map_offset,
307+ lit_map_p,
308+ literals_num,
309+ lit_id_hash_table_buffer_p,
310+ hash_table_size)
311+ && (vm_instr_counter_t ) instructions_number == instructions_number)
312+ {
313+ jsp_bc_add_bytecode_data (header_p,
314+ (lit_id_hash_table *) lit_id_hash_table_buffer_p,
315+ instrs_p,
316+ (vm_instr_counter_t ) instructions_number);
317+
318+ return header_p;
319+ }
320+ else
321+ {
322+ mem_heap_free_block (buffer_p);
323+ return NULL ;
324+ }
325+ } /* serializer_load_bytecode_with_idx_map */
326+
327+ #endif /* JERRY_ENABLE_SNAPSHOT */
0 commit comments