Skip to content

Commit

Permalink
Initialize TR_X86ProcessorInfo once
Browse files Browse the repository at this point in the history
TR_X86ProcessorInfo is currently used in OMR because the compiler does
not yet have access to the portlib. Therefore, it has to determine the
processor features itself. In order to not initialize
TR_X86ProcessorInfo multiple times a flag is set. However, it is
a race possible if there are multiple compilations, as is the case in
Eclipse OpenJ9. Because the processor feature flags were copied from the
target TR::Environment set in TR::Compilation object, if two racing
compilations had different target environments, the feature flags could
become inconsistent.

This commit initializes the processor info just once in
OMR::CompilerEnv::initializeTargetEnvironment().

Signed-off-by: Irwin D'Souza <dsouzai.gh@gmail.com>
  • Loading branch information
dsouzai committed Apr 7, 2021
1 parent 7c7d075 commit be400f0
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 50 deletions.
5 changes: 1 addition & 4 deletions compiler/env/JitConfig.hpp
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -47,9 +47,6 @@ class JitConfig
uint64_t verboseFlags;
} options;

void *getProcessorInfo() { return _processorInfo; }
void setProcessorInfo(void *buf) { _processorInfo = buf; }

void setInterpreterTOC(size_t interpreterTOC) { _interpreterTOC = interpreterTOC; }
size_t getInterpreterTOC() { return _interpreterTOC; }

Expand Down
5 changes: 5 additions & 0 deletions compiler/env/OMRCPU.hpp
Expand Up @@ -114,6 +114,11 @@ class OMR_EXTENSIBLE CPU
*/
static TR::CPU detectRelocatable(OMRPortLibrary * const omrPortLib);

/**
* @brief API to initialize platform specific target processor info if it exists
*/
static void initializeTargetProcessorInfo() {}

TR_Processor setProcessor(TR_Processor p) { return(_processor = p); }

// Processor identity and generation comparisons
Expand Down
3 changes: 2 additions & 1 deletion compiler/env/OMRCompilerEnv.cpp
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -124,6 +124,7 @@ OMR::CompilerEnv::initializeTargetEnvironment()
// Initialize the target CPU by querying the host processor
//
target.cpu = TR::CPU::detect(TR::Compiler->omrPortLib);
TR::CPU::initializeTargetProcessorInfo();

// Target major operating system
//
Expand Down
16 changes: 7 additions & 9 deletions compiler/x/codegen/OMRCodeGenerator.cpp
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -109,20 +109,20 @@ namespace TR { class RegisterDependencyConditions; }

TR_X86ProcessorInfo OMR::X86::CodeGenerator::_targetProcessorInfo;

void TR_X86ProcessorInfo::initialize(TR::CodeGenerator *cg)
void TR_X86ProcessorInfo::initialize()
{
if (_featureFlags.testAny(TR_X86ProcessorInfoInitialized))
return;
// For now, we only convert the feature bits into a flags32_t, for easier querying.
// To retrieve other information, the VM functions can be called directly.
//
_featureFlags.set(cg->comp()->target().cpu.getX86ProcessorFeatureFlags());
_featureFlags2.set(cg->comp()->target().cpu.getX86ProcessorFeatureFlags2());
_featureFlags8.set(cg->comp()->target().cpu.getX86ProcessorFeatureFlags8());
_featureFlags.set(TR::Compiler->target.cpu.getX86ProcessorFeatureFlags());
_featureFlags2.set(TR::Compiler->target.cpu.getX86ProcessorFeatureFlags2());
_featureFlags8.set(TR::Compiler->target.cpu.getX86ProcessorFeatureFlags8());

// Determine the processor vendor.
//
const char *vendor = cg->comp()->target().cpu.getX86ProcessorVendorId();
const char *vendor = TR::Compiler->target.cpu.getX86ProcessorVendorId();
if (!strncmp(vendor, "GenuineIntel", 12))
_vendorFlags.set(TR_GenuineIntel);
else if (!strncmp(vendor, "AuthenticAMD", 12))
Expand All @@ -139,7 +139,7 @@ void TR_X86ProcessorInfo::initialize(TR::CodeGenerator *cg)

// set up the processor family and cache description

uint32_t _processorSignature = cg->comp()->target().cpu.getX86ProcessorSignature();
uint32_t _processorSignature = TR::Compiler->target.cpu.getX86ProcessorSignature();

if (isGenuineIntel())
{
Expand Down Expand Up @@ -206,9 +206,7 @@ void TR_X86ProcessorInfo::initialize(TR::CodeGenerator *cg)
void
OMR::X86::CodeGenerator::initializeX86(TR::Compilation *comp)
{

bool supportsSSE2 = false;
_targetProcessorInfo.initialize(self());

TR_ASSERT_FATAL(comp->compileRelocatableCode() || comp->isOutOfProcessCompilation() || comp->target().cpu.isGenuineIntel() == _targetProcessorInfo.isGenuineIntel(), "isGenuineIntel() failed\n");
TR_ASSERT_FATAL(comp->compileRelocatableCode() || comp->isOutOfProcessCompilation() || comp->target().cpu.isAuthenticAMD() == _targetProcessorInfo.isAuthenticAMD(), "isAuthenticAMD() failed\n");
Expand Down
5 changes: 3 additions & 2 deletions compiler/x/codegen/OMRCodeGenerator.hpp
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -223,7 +223,7 @@ struct TR_X86ProcessorInfo

friend class OMR::X86::CodeGenerator;

void initialize(TR::CodeGenerator *cg);
void initialize();

/**
* @brief testFlag Ensures that the feature being tested for exists in the mask
Expand Down Expand Up @@ -343,6 +343,7 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator


static TR_X86ProcessorInfo &getX86ProcessorInfo() {return _targetProcessorInfo;}
static void initializeX86TargetProcessorInfo() { _targetProcessorInfo.initialize(); }

typedef enum
{
Expand Down
51 changes: 18 additions & 33 deletions compiler/x/env/OMRCPU.cpp
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -69,44 +69,23 @@ OMR::X86::CPU::detect(OMRPortLibrary * const omrPortLib)
return TR::CPU(processorDescription);
}

void
OMR::X86::CPU::initializeTargetProcessorInfo()
{
OMR::X86::CodeGenerator::initializeX86TargetProcessorInfo();
}

TR_X86CPUIDBuffer *
OMR::X86::CPU::queryX86TargetCPUID()
{
static TR_X86CPUIDBuffer *buf = NULL;
auto jitConfig = TR::JitConfig::instance();

if (jitConfig && jitConfig->getProcessorInfo() == NULL)
if (!buf)
{
buf = (TR_X86CPUIDBuffer *) malloc(sizeof(TR_X86CPUIDBuffer));
buf = reinterpret_cast<TR_X86CPUIDBuffer *>(malloc(sizeof(TR_X86CPUIDBuffer)));
if (!buf)
return 0;
return NULL;
jitGetCPUID(buf);
jitConfig->setProcessorInfo(buf);
}
else
{
if (!buf)
{
if (jitConfig && jitConfig->getProcessorInfo())
{
buf = (TR_X86CPUIDBuffer *)jitConfig->getProcessorInfo();
}
else
{
buf = (TR_X86CPUIDBuffer *) malloc(sizeof(TR_X86CPUIDBuffer));

if (!buf)
memcpy(buf->_vendorId, "Poughkeepsie", 12); // 12 character dummy string (NIL term not used)

buf->_processorSignature = 0;
buf->_brandIdEtc = 0;
buf->_featureFlags = 0x00000000;
buf->_cacheDescription.l1instr = 0;
buf->_cacheDescription.l1data = 0;
buf->_cacheDescription.l2 = 0;
buf->_cacheDescription.l3 = 0;
}
}
}

return buf;
Expand Down Expand Up @@ -254,7 +233,10 @@ OMR::X86::CPU::is(OMRProcessorArchitecture p)
{
if (TR::Compiler->omrPortLib == NULL)
return self()->is_old_api(p);
TR_ASSERT_FATAL(self()->is_test(p), "old api and new api did not match, processor %d", p);

static bool disableOldVersionCPUDetectionTest = feGetEnv("TR_DisableOldVersionCPUDetectionTest");
if (!disableOldVersionCPUDetectionTest)
TR_ASSERT_FATAL(self()->is_test(p), "old api and new api did not match, processor %d", p);

return _processorDescription.processor == p;
}
Expand All @@ -264,7 +246,10 @@ OMR::X86::CPU::supportsFeature(uint32_t feature)
{
if (TR::Compiler->omrPortLib == NULL)
return self()->supports_feature_old_api(feature);
TR_ASSERT_FATAL(self()->supports_feature_test(feature), "old api and new api did not match, feature %d", feature);

static bool disableOldVersionCPUDetectionTest = feGetEnv("TR_DisableOldVersionCPUDetectionTest");
if (!disableOldVersionCPUDetectionTest)
TR_ASSERT_FATAL(self()->supports_feature_test(feature), "old api and new api did not match, feature %d", feature);

OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib);
return TRUE == omrsysinfo_processor_has_feature(&_processorDescription, feature);
Expand Down
4 changes: 3 additions & 1 deletion compiler/x/env/OMRCPU.hpp
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corp. and others
* Copyright (c) 2000, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -59,6 +59,8 @@ class OMR_EXTENSIBLE CPU : public OMR::CPU

static TR::CPU detect(OMRPortLibrary * const omrPortLib);

static void initializeTargetProcessorInfo();

TR_X86CPUIDBuffer *queryX86TargetCPUID();
const char *getX86ProcessorVendorId();
uint32_t getX86ProcessorSignature();
Expand Down

0 comments on commit be400f0

Please sign in to comment.