Bug 12433 - Linking libjvm.so with LTO fails with undefined references
Summary: Linking libjvm.so with LTO fails with undefined references
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-24 10:46 UTC by Trevor Hemsley
Modified: 2016-03-27 17:09 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Trevor Hemsley 2011-01-24 10:46:05 UTC
I've been compiling Sun/Oracle Java 1.6.0_23 with gcc 4.5.1 and 4.6.0 to see if a) it can be done (it can) and b) if there are any performance improvements to be made (dubious). One of the things that I have tried is using LTO on the resulting files. 

With gcc 4.6.0 20110115, this mostly works until I try to add -flto to the link that creates libjvm.so. Using binutils from cvs head, this fails to link with about 20 pages of undefined references. There was a patch posted to the gcc mailing list recently with the subject "PATCH: 2 stage BFD linker for LTO plugin" and applying this to binutils does help immensely - it reduces the undefined references from ~20 pages down to 13 individual items. However, it uses ~5.7GB of my 4GB RAM and takes about 12 hours to link. A non-lto link of the same items appears to use ~700MB RAM and takes a second or two.

The problematic command generated by the build process is

/usr/local/gcc46/bin/gcc -m64 -Xlinker -O1   -shared -Xlinker --version-script=mapfile_reorder -Xlinker -soname=libjvm.so -static-libgcc -o libjvm.so abstractCompiler.o accessFlags.o ad_x86_64.o ad_x86_64_clone.o ad_x86_64_expand.o ad_x86_64_format.o ad_x86_64_gen.o ad_x86_64_misc.o ad_x86_64_peephole.o ad_x86_64_pipeline.o adaptiveSizePolicy.o addnode.o adjoiningGenerations.o adjoiningVirtualSpaces.o ageTable.o allocation.o allocationStats.o aprofiler.o arguments.o array.o arrayKlass.o arrayKlassKlass.o arrayOop.o asPSOldGen.o asPSYoungGen.o asParNewGeneration.o assembler.o assembler_linux_x86.o assembler_x86.o atomic.o attachListener.o attachListener_linux.o barrierSet.o bcEscapeAnalyzer.o biasedLocking.o binaryTreeDictionary.o bitMap.o block.o blockOffsetTable.o buildOopMap.o bytecode.o bytecodeHistogram.o bytecodeInfo.o bytecodeInterpreter.o bytecodeInterpreterWithChecks.o bytecodeInterpreter_x86.o bytecodeStream.o bytecodeTracer.o bytecodes.o bytecodes_x86.o c2_globals.o c2_init_x86.o c2compiler.o cSpaceCounters.o callGenerator.o callnode.o cardTableExtension.o cardTableModRefBS.o cardTableRS.o cfgnode.o chaitin.o chaitin_linux.o ciArray.o ciArrayKlass.o ciCPCache.o ciCallSite.o ciConstant.o ciConstantPoolCache.o ciEnv.o ciExceptionHandler.o ciField.o ciFlags.o ciInstance.o ciInstanceKlass.o ciInstanceKlassKlass.o ciKlass.o ciKlassKlass.o ciMethod.o ciMethodBlocks.o ciMethodData.o ciMethodHandle.o ciMethodKlass.o ciNullObject.o ciObjArray.o ciObjArrayKlass.o ciObjArrayKlassKlass.o ciObject.o ciObjectFactory.o ciSignature.o ciStreams.o ciSymbol.o ciSymbolKlass.o ciType.o ciTypeArray.o ciTypeArrayKlass.o ciTypeArrayKlassKlass.o ciTypeFlow.o ciUtilities.o classFileError.o classFileParser.o classFileStream.o classLoader.o classLoadingService.o classes.o classify.o cmsAdaptiveSizePolicy.o cmsCollectorPolicy.o cmsGCAdaptivePolicyCounters.o cmsLockVerifier.o cmsPermGen.o coalesce.o codeBlob.o codeBuffer.o codeCache.o collectedHeap.o collectionSetChooser.o collectorCounters.o collectorPolicy.o compactibleFreeListSpace.o compactingPermGenGen.o compilationPolicy.o compile.o compileBroker.o compileLog.o compiledIC.o compiledICHolderKlass.o compiledICHolderOop.o compilerOracle.o compressedStream.o concurrentG1Refine.o concurrentG1RefineThread.o concurrentGCThread.o concurrentMark.o concurrentMarkSweepGeneration.o concurrentMarkSweepThread.o concurrentMarkThread.o concurrentZFThread.o connode.o constMethodKlass.o constMethodOop.o constantPoolKlass.o constantPoolOop.o constantTag.o copy.o cpCacheKlass.o cpCacheOop.o cppInterpreter.o cppInterpreter_x86.o debug.o debugInfo.o debugInfoRec.o debug_x86.o defNewGeneration.o deoptimization.o depChecker_x86.o dependencies.o dfa_x86_64.o dict.o dictionary.o dirtyCardQueue.o disassembler.o divnode.o doCall.o domgraph.o dtraceAttacher.o dtraceJSDT.o dtraceJSDT_linux.o dump.o dump_x86_64.o escape.o events.o evmCompat.o exceptionHandlerTable.o exceptions.o fieldDescriptor.o fieldType.o filemap.o forte.o fprofiler.o frame.o frame_x86.o freeBlockDictionary.o freeChunk.o freeList.o g1BlockOffsetTable.o g1CollectedHeap.o g1CollectorPolicy.o g1MMUTracker.o g1MarkSweep.o g1MemoryPool.o g1RemSet.o g1SATBCardTableModRefBS.o g1_globals.o gSpaceCounters.o gcAdaptivePolicyCounters.o gcCause.o gcLocker.o gcPolicyCounters.o gcStats.o gcTaskManager.o gcTaskThread.o gcUtil.o gcm.o genCollectedHeap.o genMarkSweep.o genRemSet.o generateOopMap.o generateOptoStub.o generation.o generationCounters.o generationSpec.o globalDefinitions.o globals.o graphKit.o growableArray.o handles.o hashtable.o heap.o heapDumper.o heapInspection.o heapRegion.o heapRegionRemSet.o heapRegionSeq.o histogram.o hpi.o hpi_linux.o icBuffer.o icBuffer_x86.o icache.o icache_x86.o idealKit.o ifg.o ifnode.o immutableSpace.o indexSet.o init.o instanceKlass.o instanceKlassKlass.o instanceOop.o instanceRefKlass.o intHisto.o interfaceSupport.o interp_masm_x86_64.o interpreter.o interpreterRT_x86_64.o interpreterRuntime.o interpreter_x86_64.o invocationCounter.o iterator.o java.o javaAssertions.o javaCalls.o javaClasses.o jni.o jniCheck.o jniFastGetField.o jniFastGetField_x86_64.o jniHandles.o jniPeriodicChecker.o jvm.o jvm_linux.o jvmtiClassFileReconstituter.o jvmtiCodeBlobEvents.o jvmtiEnter.o jvmtiEnterTrace.o jvmtiEnv.o jvmtiEnvBase.o jvmtiEnvThreadState.o jvmtiEventController.o jvmtiExport.o jvmtiExtensions.o jvmtiGetLoadedClasses.o jvmtiImpl.o jvmtiManageCapabilities.o jvmtiRedefineClasses.o jvmtiTagMap.o jvmtiThreadState.o jvmtiTrace.o jvmtiUtil.o klass.o klassKlass.o klassOop.o klassVtable.o lcm.o library_call.o linkResolver.o live.o loaderConstraints.o location.o locknode.o loopTransform.o loopUnswitch.o loopnode.o loopopts.o lowMemoryDetector.o machnode.o macro.o management.o markOop.o markSweep.o matcher.o memRegion.o memnode.o memoryManager.o memoryPool.o memoryService.o memprofiler.o methodComparator.o methodDataKlass.o methodDataOop.o methodHandleWalk.o methodHandles.o methodHandles_x86.o methodKlass.o methodLiveness.o methodOop.o monitorChunk.o mulnode.o multnode.o mutableNUMASpace.o mutableSpace.o mutex.o mutexLocker.o mutex_linux.o nativeInst_x86.o nativeLookup.o nmethod.o node.o numberSeq.o objArrayKlass.o objArrayKlassKlass.o objArrayOop.o objectMonitor_linux.o objectStartArray.o oop.o oopFactory.o oopMap.o oopMapCache.o oopRecorder.o oopsHierarchy.o opcodes.o orderAccess.o os.o osThread.o osThread_linux.o os_linux.o os_linux_x86.o ostream.o output.o parCardTableModRefBS.o parGCAllocBuffer.o parMarkBitMap.o parNewGeneration.o parallelScavengeHeap.o parse1.o parse2.o parse3.o parseHelper.o pcDesc.o pcTasks.o perf.o perfData.o perfMemory.o perfMemory_linux.o permGen.o phase.o phaseX.o placeholders.o port.o postaloc.o preserveException.o privilegedStack.o promotionInfo.o psAdaptiveSizePolicy.o psCompactionManager.o psGCAdaptivePolicyCounters.o psGenerationCounters.o psMarkSweep.o psMarkSweepDecorator.o psMemoryPool.o psOldGen.o psParallelCompact.o psPermGen.o psPromotionLAB.o psPromotionManager.o psScavenge.o psTasks.o psVirtualspace.o psYoungGen.o ptrQueue.o referencePolicy.o referenceProcessor.o reflection.o reflectionUtils.o reg_split.o regalloc.o register.o register_definitions_x86.o register_x86.o regmask.o relocInfo.o relocInfo_x86.o relocator.o resolutionErrors.o resourceArea.o restore.o rewriter.o rframe.o rootnode.o runtime.o runtimeService.o runtime_x86_64.o safepoint.o satbQueue.o scopeDesc.o serialize.o set.o sharedHeap.o sharedRuntime.o sharedRuntimeTrans.o sharedRuntimeTrig.o sharedRuntime_x86_64.o signature.o sizes.o space.o spaceCounters.o spaceDecorator.o sparsePRT.o specialized_oop_closures.o split_if.o stackMapFrame.o stackMapTable.o stackValue.o stackValueCollection.o statSampler.o stringopts.o stubCodeGenerator.o stubGenerator_x86_64.o stubRoutines.o stubRoutines_linux.o stubRoutines_x86_64.o stubs.o subnode.o superword.o survRateGroup.o sweeper.o symbolKlass.o symbolOop.o symbolTable.o synchronizer.o systemDictionary.o task.o taskqueue.o templateInterpreter.o templateInterpreter_x86_64.o templateTable.o templateTable_x86_64.o tenuredGeneration.o thread.o threadCritical_linux.o threadLS_linux_x86.o threadLocalAllocBuffer.o threadLocalStorage.o threadService.o thread_linux_x86.o timer.o type.o typeArrayKlass.o typeArrayKlassKlass.o typeArrayOop.o unhandledOops.o universe.o unsafe.o utf8.o vectornode.o vectset.o verificationType.o verifier.o vframe.o vframeArray.o vframe_hp.o virtualspace.o vmCMSOperations.o vmError.o vmError_linux.o vmGCOperations.o vmPSOperations.o vmStructs.o vmSymbols.o vmThread.o vm_operations.o vm_operations_g1.o vm_version.o vm_version_linux_x86.o vm_version_x86.o vmreg.o vmreg_x86.o vtableStubs.o vtableStubs_x86_64.o workgroup.o xmlstream.o yieldingWorkgroup.o idealGraphPrinter.o  linux_x86_64.o -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic -lm -ldl -lpthread -flto  -fuse-linker-plugin

Retrieving that command and removing "-flto  -fuse-linker-plugin" and rerunning it allows the link to complete and generate a libjvm.so that has no undefined references (beyond those expected in external .so files).

The undefined external references listed by the LTO version of the same command are

/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void G1ParPushHeapRSClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void FilterOutOfRegionClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void FilterAndMarkInHeapRegionAndIntoCSClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void HRInto_G1RemSet::write_ref_nv<unsigned int>(HeapRegion*, unsigned int*)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void FilterIntoCSClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void UpdateRSetImmediate::do_oop_work<unsigned int>(unsigned int*)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void FilterInHeapRegionAndIntoCSClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void UpdateRSetImmediate::do_oop_work<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void UpdateRSOopClosure::do_oop_work<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void UpdateRSOopClosure::do_oop_work<unsigned int>(unsigned int*)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void G1ParScanClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `HeapRegionSeq::addr_to_region(void const*)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void HRInto_G1RemSet::write_ref_nv<oopDesc*>(HeapRegion*, oopDesc**)'
Comment 1 H.J. Lu 2011-01-24 14:01:01 UTC
Can you try GNU ld on hjl/lto-mixed branch from

http://git.kernel.org/?p=devel/binutils/hjl/x86.git;a=shortlog;h=refs/heads/hjl/lto-mixed
Comment 2 Trevor Hemsley 2011-01-25 02:14:25 UTC
That branch also helps reduce the undefined refs even further. I did notice that memory usage peaked at 6.4GB this time round but the trunk+patch version may have got to that too because it dropped back after a few minutes to 5.7GB. The undefined refs with binutils-hjl are now

/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void G1ParPushHeapRSClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void FilterOutOfRegionClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void FilterAndMarkInHeapRegionAndIntoCSClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void FilterIntoCSClosure::do_oop_nv<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void UpdateRSOopClosure::do_oop_work<oopDesc*>(oopDesc**)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void UpdateRSOopClosure::do_oop_work<unsigned int>(unsigned int*)'
/sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so: undefined reference to `void G1ParScanClosure::do_oop_nv<oopDesc*>(oopDesc**)'
Comment 3 H.J. Lu 2011-01-25 02:20:53 UTC
(In reply to comment #2)
> That branch also helps reduce the undefined refs even further. I did notice
> that memory usage peaked at 6.4GB this time round but the trunk+patch version
> may have got to that too because it dropped back after a few minutes to 5.7GB.
> The undefined refs with binutils-hjl are now
> 
> /sources/java/control/build/linux-amd64/hotspot/outputdir/linux_amd64_compiler2/product/libjvm.so:
> undefined reference to `void
> G1ParPushHeapRSClosure::do_oop_nv<oopDesc*>(oopDesc**)'
...

You should try new gold Ian just updated.

Do you get undefined symbols without -flto -fuse-linker-plugin at
the final link?
Comment 4 Trevor Hemsley 2011-01-25 02:30:55 UTC
No undefined symbols without -flto -fuse-linker-plugin

I've just transplanted this system onto a different one with 6GB RAM so I don't have to wait 12 hours for the link to complete! It's currently rerunning the build with a rebuilt version of your binutils and if this fails I will update to the latest and retry.
Comment 5 Trevor Hemsley 2011-01-25 03:34:03 UTC
The rerun with binutils-hjl failed with the same 7 undefs as before. I checked out the latest binutils trunk including the gold 1.11 version.cc and rebuilt and this reverts to failing with the 13 undefs as in the original report.
Comment 6 H.J. Lu 2011-01-25 04:57:56 UTC
You may run into

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47247
Comment 7 Ian Lance Taylor 2011-07-09 05:36:17 UTC
This report was filed against gold, but the error messages are from GNU ld, not gold.  Which linker are you using?  Should this be filed against ld rather than gold?
Comment 8 Cary Coutant 2016-03-27 17:09:29 UTC
I think that has been fixed for a while now, closing.