comparison gen/classes.cpp @ 284:70c370e97944 trunk

[svn r305] Started support for custom class allocators/deallocators. Allocators with more than one argument still need to be fixed. Removed the LLVM stacktrace code from mars.c. Moved the LLVM based default target detection code from mars.c to llvmhelpers.cpp.
author lindquist
date Sat, 21 Jun 2008 02:48:53 +0200
parents 665b81613475
children 297690b5d4a5
comparison
equal deleted inserted replaced
283:9bb48fb57a7d 284:70c370e97944
792 LLValue* mem; 792 LLValue* mem;
793 if (newexp->onstack) 793 if (newexp->onstack)
794 { 794 {
795 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); 795 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint());
796 } 796 }
797 // custom allocator
798 else if (newexp->allocator)
799 {
800 DtoForceDeclareDsymbol(newexp->allocator);
801 assert(newexp->newargs);
802 assert(newexp->newargs->dim == 1);
803
804 llvm::Function* fn = newexp->allocator->ir.irFunc->func;
805 assert(fn);
806 DValue* arg = ((Expression*)newexp->newargs->data[0])->toElem(gIR);
807 mem = gIR->ir->CreateCall(fn, arg->getRVal(), "newclass_custom_alloc");
808 mem = DtoBitCast(mem, DtoType(tc), "newclass_custom");
809 }
810 // default allocator
797 else 811 else
798 { 812 {
799 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); 813 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass");
800 mem = gIR->ir->CreateCall(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc"); 814 mem = gIR->ir->CreateCall(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc");
801 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); 815 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc");
1444 1458
1445 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 1459 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
1446 DtoForceConstInitDsymbol(cinfo); 1460 DtoForceConstInitDsymbol(cinfo);
1447 assert(cinfo->ir.irStruct->constInit); 1461 assert(cinfo->ir.irStruct->constInit);
1448 1462
1463 // def init constant
1464 LLConstant* defc = cinfo->ir.irStruct->constInit;
1465 assert(defc);
1466
1449 LLConstant* c; 1467 LLConstant* c;
1450 1468
1451 // own vtable 1469 // own vtable
1452 c = cinfo->ir.irStruct->constInit->getOperand(0); 1470 c = defc->getOperand(0);
1453 assert(c); 1471 assert(c);
1454 inits.push_back(c); 1472 inits.push_back(c);
1455 1473
1456 // monitor 1474 // monitor
1457 c = cinfo->ir.irStruct->constInit->getOperand(1); 1475 c = defc->getOperand(1);
1458 inits.push_back(c); 1476 inits.push_back(c);
1459 1477
1460 // byte[] init 1478 // byte[] init
1461 const LLType* byteptrty = getPtrToType(LLType::Int8Ty); 1479 const LLType* byteptrty = getPtrToType(LLType::Int8Ty);
1462 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1480 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1463 c = cinfo->ir.irStruct->constInit->getOperand(2); 1481 c = defc->getOperand(2);
1464 } 1482 }
1465 else { 1483 else {
1466 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->init, byteptrty); 1484 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->init, byteptrty);
1467 assert(!cd->ir.irStruct->constInit->getType()->isAbstract()); 1485 assert(!defc->getType()->isAbstract());
1468 size_t initsz = getABITypeSize(cd->ir.irStruct->constInit->getType()); 1486 size_t initsz = getABITypeSize(defc->getType());
1469 c = DtoConstSlice(DtoConstSize_t(initsz), c); 1487 c = DtoConstSlice(DtoConstSize_t(initsz), c);
1470 } 1488 }
1471 inits.push_back(c); 1489 inits.push_back(c);
1472 1490
1473 // class name 1491 // class name
1482 c = DtoConstString(name); 1500 c = DtoConstString(name);
1483 inits.push_back(c); 1501 inits.push_back(c);
1484 1502
1485 // vtbl array 1503 // vtbl array
1486 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1504 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1487 c = cinfo->ir.irStruct->constInit->getOperand(4); 1505 c = defc->getOperand(4);
1488 } 1506 }
1489 else { 1507 else {
1490 const LLType* byteptrptrty = getPtrToType(byteptrty); 1508 const LLType* byteptrptrty = getPtrToType(byteptrty);
1491 assert(!cd->ir.irStruct->vtbl->getType()->isAbstract()); 1509 assert(!cd->ir.irStruct->vtbl->getType()->isAbstract());
1492 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty); 1510 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty);
1501 inits.push_back(c); 1519 inits.push_back(c);
1502 1520
1503 // interfaces array 1521 // interfaces array
1504 IrStruct* irstruct = cd->ir.irStruct; 1522 IrStruct* irstruct = cd->ir.irStruct;
1505 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { 1523 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) {
1506 c = cinfo->ir.irStruct->constInit->getOperand(5); 1524 c = defc->getOperand(5);
1507 } 1525 }
1508 else { 1526 else {
1509 const LLType* t = cinfo->ir.irStruct->constInit->getOperand(5)->getType()->getContainedType(1); 1527 const LLType* t = defc->getOperand(5)->getType()->getContainedType(1);
1510 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); 1528 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t);
1511 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); 1529 size_t iisz = irstruct->interfaceInfosTy->getNumElements();
1512 c = DtoConstSlice(DtoConstSize_t(iisz), c); 1530 c = DtoConstSlice(DtoConstSize_t(iisz), c);
1513 } 1531 }
1514 inits.push_back(c); 1532 inits.push_back(c);
1520 assert(c); 1538 assert(c);
1521 inits.push_back(c); 1539 inits.push_back(c);
1522 } 1540 }
1523 else { 1541 else {
1524 // null 1542 // null
1525 c = cinfo->ir.irStruct->constInit->getOperand(6); 1543 c = defc->getOperand(6);
1526 inits.push_back(c); 1544 inits.push_back(c);
1527 } 1545 }
1528 1546
1529 // destructor 1547 // destructor
1530 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1548 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1531 c = cinfo->ir.irStruct->constInit->getOperand(7); 1549 c = defc->getOperand(7);
1532 } 1550 }
1533 else { 1551 else {
1534 c = build_class_dtor(cd); 1552 c = build_class_dtor(cd);
1535 } 1553 }
1536 inits.push_back(c); 1554 inits.push_back(c);
1537 1555
1538 // invariant 1556 // invariant
1539 // TODO 1557 // TODO
1540 c = cinfo->ir.irStruct->constInit->getOperand(8); 1558 c = defc->getOperand(8);
1541 inits.push_back(c); 1559 inits.push_back(c);
1542 1560
1543 // uint flags 1561 // uint flags
1544 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1562 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1545 c = cinfo->ir.irStruct->constInit->getOperand(9); 1563 c = defc->getOperand(9);
1546 } 1564 }
1547 else { 1565 else {
1548 uint flags = build_classinfo_flags(cd); 1566 uint flags = build_classinfo_flags(cd);
1549 c = DtoConstUint(flags); 1567 c = DtoConstUint(flags);
1550 } 1568 }
1551 inits.push_back(c); 1569 inits.push_back(c);
1552 1570
1553 // allocator 1571 // deallocator
1554 // TODO 1572 if (cd->aggDelete) {
1555 c = cinfo->ir.irStruct->constInit->getOperand(10); 1573 DtoForceDeclareDsymbol(cd->aggDelete);
1574 c = cd->aggDelete->ir.irFunc->func;
1575 c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(10)->getType());
1576 }
1577 else {
1578 c = defc->getOperand(10);
1579 }
1556 inits.push_back(c); 1580 inits.push_back(c);
1557 1581
1558 // offset typeinfo 1582 // offset typeinfo
1559 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1583 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1560 c = cinfo->ir.irStruct->constInit->getOperand(11); 1584 c = defc->getOperand(11);
1561 } 1585 }
1562 else { 1586 else {
1563 c = build_offti_array(cd, cinfo->ir.irStruct->constInit->getOperand(11)); 1587 c = build_offti_array(cd, defc->getOperand(11));
1564 } 1588 }
1565 inits.push_back(c); 1589 inits.push_back(c);
1566 1590
1567 // default constructor 1591 // default constructor
1568 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1592 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1569 DtoForceDeclareDsymbol(cd->defaultCtor); 1593 DtoForceDeclareDsymbol(cd->defaultCtor);
1570 c = isaConstant(cd->defaultCtor->ir.irFunc->func); 1594 c = isaConstant(cd->defaultCtor->ir.irFunc->func);
1571 const LLType* toTy = cinfo->ir.irStruct->constInit->getOperand(12)->getType(); 1595 const LLType* toTy = defc->getOperand(12)->getType();
1572 c = llvm::ConstantExpr::getBitCast(c, toTy); 1596 c = llvm::ConstantExpr::getBitCast(c, toTy);
1573 } 1597 }
1574 else { 1598 else {
1575 c = cinfo->ir.irStruct->constInit->getOperand(12); 1599 c = defc->getOperand(12);
1576 } 1600 }
1577 inits.push_back(c); 1601 inits.push_back(c);
1578 1602
1579 /*size_t n = inits.size(); 1603 /*size_t n = inits.size();
1580 for (size_t i=0; i<n; ++i) 1604 for (size_t i=0; i<n; ++i)
1581 { 1605 {
1582 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; 1606 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n';
1583 }*/ 1607 }*/
1584 1608
1585 // build the initializer 1609 // build the initializer
1586 const llvm::StructType* st = isaStruct(cinfo->ir.irStruct->constInit->getType()); 1610 const llvm::StructType* st = isaStruct(defc->getType());
1587 LLConstant* finalinit = llvm::ConstantStruct::get(st, inits); 1611 LLConstant* finalinit = llvm::ConstantStruct::get(st, inits);
1588 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; 1612 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n';
1589 1613
1590 cd->ir.irStruct->constClassInfo = finalinit; 1614 cd->ir.irStruct->constClassInfo = finalinit;
1591 cd->ir.irStruct->classInfo->setInitializer(finalinit); 1615 cd->ir.irStruct->classInfo->setInitializer(finalinit);