| 1523 | } |
| 1524 | |
| 1525 | void SlotDescriptor::CodegenWriteCollectionVarlenChild(LlvmCodeGen* codegen, |
| 1526 | LlvmBuilder* builder, llvm::Value* master_tuple, llvm::Value* children_tuple, |
| 1527 | llvm::Function* fn, const NonWritableBasicBlock& insert_before, |
| 1528 | llvm::Value* pool_val) const { |
| 1529 | DCHECK(pool_val != nullptr); |
| 1530 | DCHECK(type_.IsVarLenStringType() || type_.IsCollectionType()); |
| 1531 | |
| 1532 | llvm::BasicBlock* child_non_null_block = insert_before.CreateBasicBlockBefore( |
| 1533 | codegen->context(), "child_non_null_block", fn); |
| 1534 | llvm::BasicBlock* child_written_block = insert_before.CreateBasicBlockBefore( |
| 1535 | codegen->context(), "next_block_after_child_is_written", fn); |
| 1536 | |
| 1537 | llvm::Value* child_is_null = CodegenIsNull(codegen, builder, master_tuple); |
| 1538 | builder->CreateCondBr(child_is_null, child_written_block, child_non_null_block); |
| 1539 | |
| 1540 | // Note: Although the input of CodegenWriteStringOrCollectionToSlot() is a '*Val', not a |
| 1541 | // '*Value', the items of a collection are still '*Value' objects, because the pointer |
| 1542 | // of the collection points to an array of tuples (the items). 'StringValue' has Small |
| 1543 | // String Optimisation, but smallness is not preserved here: even if the 'StringValue' |
| 1544 | // was originally small, the new copy will be a long string. |
| 1545 | builder->SetInsertPoint(child_non_null_block); |
| 1546 | llvm::Value* child_str_or_coll_value_slot = builder->CreateStructGEP(nullptr, |
| 1547 | children_tuple, llvm_field_idx(), "child_str_or_coll_value_addr"); |
| 1548 | llvm::Value* child_str_or_coll_value_ptr = CodegenStrOrCollValueGetPtr(codegen, builder, |
| 1549 | child_str_or_coll_value_slot, "child_str_or_coll_value_ptr"); |
| 1550 | llvm::Value* child_str_or_coll_value_len = CodegenStrOrCollValueGetLen(codegen, builder, |
| 1551 | child_str_or_coll_value_slot, "child_str_or_coll_value_len"); |
| 1552 | |
| 1553 | CodegenAnyValReadWriteInfo child_rwi(codegen, builder, type()); |
| 1554 | child_rwi.SetPtrAndLen(child_str_or_coll_value_ptr, child_str_or_coll_value_len); |
| 1555 | |
| 1556 | CodegenWriteStringOrCollectionToSlot(child_rwi, child_str_or_coll_value_slot, pool_val, |
| 1557 | this, insert_before); |
| 1558 | builder->CreateBr(child_written_block); |
| 1559 | builder->SetInsertPoint(child_written_block); |
| 1560 | } |
| 1561 | |
| 1562 | llvm::Value* SlotDescriptor::CodegenToTimestampValue( |
| 1563 | const CodegenAnyValReadWriteInfo& read_write_info) { |
no test coverage detected