338 339 // Creating new value by copying the one passed in argument 340 bool in_heap; 341 instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap, 342 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize)); 343 Handle new_value_h = Handle(THREAD, new_value); 344 int first_offset = vklass->first_field_offset(); 345 vklass->value_store(vklass->data_for_oop(old_value_h()), 346 vklass->data_for_oop(new_value_h()), in_heap, false); 347 348 // Updating the field specified in arguments 349 if (field_type == T_ARRAY) { 350 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 351 assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type"); 352 if (in_heap) { 353 new_value_h()->obj_field_put(field_offset, aoop); 354 } else { 355 new_value_h()->obj_field_put_raw(field_offset, aoop); 356 } 357 } else if (field_type == T_OBJECT) { 358 // Logic below is optimized 359 // Null checks for non flattenable fields have already be performed in the assembly template 360 // of the interpreter, which reduces the number of possible cases: 361 // 1 - flattened or not flattened 362 // 2 - if not flattened: argument is buffered (value) or in heap (value and objects) 363 if (cp_entry->is_flattened()) { 364 Klass* field_k = vklass->get_value_field_klass(field_index); 365 ValueKlass* field_vk = ValueKlass::cast(field_k); 366 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 367 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type"); 368 assert(field_vk == vt_oop->klass(), "Must match"); 369 field_vk->value_store(field_vk->data_for_oop(vt_oop), 370 ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false); 371 } else { // not flattened 372 oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 373 assert(voop != NULL || !cp_entry->is_flattenable(), 374 "NULL checks for non flattenable fields must have been performed in interpreter assembly template"); 375 assert(voop == NULL || oopDesc::is_oop(voop),"checking argument"); 376 if (VTBuffer::is_in_vt_buffer(voop)) { 377 // new value field is currently allocated in a TLVB, a heap allocated 378 // copy must be created because a field must never point to a TLVB allocated value 379 Handle voop_h = Handle(THREAD, voop); 380 ValueKlass* field_vk = ValueKlass::cast(voop->klass()); 381 assert(!cp_entry->is_flattenable() || field_vk == vklass->get_value_field_klass(field_index), "Sanity check"); 382 instanceOop field_copy = field_vk->allocate_instance(CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize)); 383 Handle field_copy_h = Handle(THREAD, field_copy); 384 field_vk->value_store(field_vk->data_for_oop(voop_h()), field_vk->data_for_oop(field_copy_h()), true, false); 385 if (in_heap) { 386 new_value_h()->obj_field_put(field_offset, field_copy_h()); 387 } else { 388 new_value_h()->obj_field_put_raw(field_offset, field_copy_h()); 389 } 390 } else { // not buffered 391 if (in_heap) { 392 new_value_h()->obj_field_put(field_offset, voop); 393 } else { 394 new_value_h()->obj_field_put_raw(field_offset, voop); | 338 339 // Creating new value by copying the one passed in argument 340 bool in_heap; 341 instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap, 342 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize)); 343 Handle new_value_h = Handle(THREAD, new_value); 344 int first_offset = vklass->first_field_offset(); 345 vklass->value_store(vklass->data_for_oop(old_value_h()), 346 vklass->data_for_oop(new_value_h()), in_heap, false); 347 348 // Updating the field specified in arguments 349 if (field_type == T_ARRAY) { 350 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 351 assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type"); 352 if (in_heap) { 353 new_value_h()->obj_field_put(field_offset, aoop); 354 } else { 355 new_value_h()->obj_field_put_raw(field_offset, aoop); 356 } 357 } else if (field_type == T_OBJECT) { 358 if (cp_entry->is_flattened()) { 359 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 360 if (vt_oop == NULL) { 361 THROW_(vmSymbols::java_lang_NullPointerException(), 362 (type2size[field_type] * AbstractInterpreter::stackElementSize)); 363 } 364 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type"); 365 Klass* field_k = vklass->get_value_field_klass(field_index); 366 ValueKlass* field_vk = ValueKlass::cast(field_k); 367 assert(field_vk == vt_oop->klass(), "Must match"); 368 field_vk->value_store(field_vk->data_for_oop(vt_oop), 369 ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false); 370 } else { // not flattened 371 oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 372 if (voop == NULL && cp_entry->is_flattenable()) { 373 THROW_(vmSymbols::java_lang_NullPointerException(), 374 (type2size[field_type] * AbstractInterpreter::stackElementSize)); 375 } 376 assert(voop == NULL || oopDesc::is_oop(voop),"checking argument"); 377 if (VTBuffer::is_in_vt_buffer(voop)) { 378 // new value field is currently allocated in a TLVB, a heap allocated 379 // copy must be created because a field must never point to a TLVB allocated value 380 Handle voop_h = Handle(THREAD, voop); 381 ValueKlass* field_vk = ValueKlass::cast(voop->klass()); 382 assert(!cp_entry->is_flattenable() || field_vk == vklass->get_value_field_klass(field_index), "Sanity check"); 383 instanceOop field_copy = field_vk->allocate_instance(CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize)); 384 Handle field_copy_h = Handle(THREAD, field_copy); 385 field_vk->value_store(field_vk->data_for_oop(voop_h()), field_vk->data_for_oop(field_copy_h()), true, false); 386 if (in_heap) { 387 new_value_h()->obj_field_put(field_offset, field_copy_h()); 388 } else { 389 new_value_h()->obj_field_put_raw(field_offset, field_copy_h()); 390 } 391 } else { // not buffered 392 if (in_heap) { 393 new_value_h()->obj_field_put(field_offset, voop); 394 } else { 395 new_value_h()->obj_field_put_raw(field_offset, voop); |