Path: blob/master/src/hotspot/share/c1/c1_Compiler.cpp
40931 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "c1/c1_Compilation.hpp"26#include "c1/c1_Compiler.hpp"27#include "c1/c1_FrameMap.hpp"28#include "c1/c1_GraphBuilder.hpp"29#include "c1/c1_LinearScan.hpp"30#include "c1/c1_MacroAssembler.hpp"31#include "c1/c1_Runtime1.hpp"32#include "c1/c1_ValueType.hpp"33#include "compiler/compileBroker.hpp"34#include "interpreter/linkResolver.hpp"35#include "jfr/support/jfrIntrinsics.hpp"36#include "memory/allocation.hpp"37#include "memory/allocation.inline.hpp"38#include "memory/resourceArea.hpp"39#include "runtime/interfaceSupport.inline.hpp"40#include "runtime/sharedRuntime.hpp"41#include "runtime/vm_version.hpp"42#include "utilities/bitMap.inline.hpp"43#include "utilities/macros.hpp"444546Compiler::Compiler() : AbstractCompiler(compiler_c1) {47}4849void Compiler::init_c1_runtime() {50BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();51Arena* arena = new (mtCompiler) Arena(mtCompiler);52Runtime1::initialize(buffer_blob);53FrameMap::initialize();54// initialize data structures55ValueType::initialize(arena);56GraphBuilder::initialize();57// note: to use more than one instance of LinearScan at a time this function call has to58// be moved somewhere outside of this constructor:59Interval::initialize(arena);60}616263void Compiler::initialize() {64// Buffer blob must be allocated per C1 compiler thread at startup65BufferBlob* buffer_blob = init_buffer_blob();6667if (should_perform_init()) {68if (buffer_blob == NULL) {69// When we come here we are in state 'initializing'; entire C1 compilation70// can be shut down.71set_state(failed);72} else {73init_c1_runtime();74set_state(initialized);75}76}77}7879int Compiler::code_buffer_size() {80return Compilation::desired_max_code_buffer_size() + Compilation::desired_max_constant_size();81}8283BufferBlob* Compiler::init_buffer_blob() {84// Allocate buffer blob once at startup since allocation for each85// compilation seems to be too expensive (at least on Intel win32).86assert (CompilerThread::current()->get_buffer_blob() == NULL, "Should initialize only once");8788// setup CodeBuffer. Preallocate a BufferBlob of size89// NMethodSizeLimit plus some extra space for constants.90BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size());91if (buffer_blob != NULL) {92CompilerThread::current()->set_buffer_blob(buffer_blob);93}9495return buffer_blob;96}9798bool Compiler::is_intrinsic_supported(const methodHandle& method) {99vmIntrinsics::ID id = method->intrinsic_id();100assert(id != vmIntrinsics::_none, "must be a VM intrinsic");101102if (method->is_synchronized()) {103// C1 does not support intrinsification of synchronized methods.104return false;105}106107switch (id) {108case vmIntrinsics::_compareAndSetLong:109if (!VM_Version::supports_cx8()) return false;110break;111case vmIntrinsics::_getAndAddInt:112if (!VM_Version::supports_atomic_getadd4()) return false;113break;114case vmIntrinsics::_getAndAddLong:115if (!VM_Version::supports_atomic_getadd8()) return false;116break;117case vmIntrinsics::_getAndSetInt:118if (!VM_Version::supports_atomic_getset4()) return false;119break;120case vmIntrinsics::_getAndSetLong:121if (!VM_Version::supports_atomic_getset8()) return false;122break;123case vmIntrinsics::_getAndSetReference:124#ifdef _LP64125if (!UseCompressedOops && !VM_Version::supports_atomic_getset8()) return false;126if (UseCompressedOops && !VM_Version::supports_atomic_getset4()) return false;127#else128if (!VM_Version::supports_atomic_getset4()) return false;129#endif130break;131case vmIntrinsics::_onSpinWait:132if (!VM_Version::supports_on_spin_wait()) return false;133break;134case vmIntrinsics::_arraycopy:135case vmIntrinsics::_currentTimeMillis:136case vmIntrinsics::_nanoTime:137case vmIntrinsics::_Reference_get:138// Use the intrinsic version of Reference.get() so that the value in139// the referent field can be registered by the G1 pre-barrier code.140// Also to prevent commoning reads from this field across safepoint141// since GC can change its value.142case vmIntrinsics::_loadFence:143case vmIntrinsics::_storeFence:144case vmIntrinsics::_fullFence:145case vmIntrinsics::_floatToRawIntBits:146case vmIntrinsics::_intBitsToFloat:147case vmIntrinsics::_doubleToRawLongBits:148case vmIntrinsics::_longBitsToDouble:149case vmIntrinsics::_getClass:150case vmIntrinsics::_isInstance:151case vmIntrinsics::_isPrimitive:152case vmIntrinsics::_getModifiers:153case vmIntrinsics::_currentThread:154case vmIntrinsics::_dabs:155case vmIntrinsics::_dsqrt:156case vmIntrinsics::_dsin:157case vmIntrinsics::_dcos:158case vmIntrinsics::_dtan:159case vmIntrinsics::_dlog:160case vmIntrinsics::_dlog10:161case vmIntrinsics::_dexp:162case vmIntrinsics::_dpow:163case vmIntrinsics::_fmaD:164case vmIntrinsics::_fmaF:165case vmIntrinsics::_getReference:166case vmIntrinsics::_getBoolean:167case vmIntrinsics::_getByte:168case vmIntrinsics::_getShort:169case vmIntrinsics::_getChar:170case vmIntrinsics::_getInt:171case vmIntrinsics::_getLong:172case vmIntrinsics::_getFloat:173case vmIntrinsics::_getDouble:174case vmIntrinsics::_putReference:175case vmIntrinsics::_putBoolean:176case vmIntrinsics::_putByte:177case vmIntrinsics::_putShort:178case vmIntrinsics::_putChar:179case vmIntrinsics::_putInt:180case vmIntrinsics::_putLong:181case vmIntrinsics::_putFloat:182case vmIntrinsics::_putDouble:183case vmIntrinsics::_getReferenceVolatile:184case vmIntrinsics::_getBooleanVolatile:185case vmIntrinsics::_getByteVolatile:186case vmIntrinsics::_getShortVolatile:187case vmIntrinsics::_getCharVolatile:188case vmIntrinsics::_getIntVolatile:189case vmIntrinsics::_getLongVolatile:190case vmIntrinsics::_getFloatVolatile:191case vmIntrinsics::_getDoubleVolatile:192case vmIntrinsics::_putReferenceVolatile:193case vmIntrinsics::_putBooleanVolatile:194case vmIntrinsics::_putByteVolatile:195case vmIntrinsics::_putShortVolatile:196case vmIntrinsics::_putCharVolatile:197case vmIntrinsics::_putIntVolatile:198case vmIntrinsics::_putLongVolatile:199case vmIntrinsics::_putFloatVolatile:200case vmIntrinsics::_putDoubleVolatile:201case vmIntrinsics::_getShortUnaligned:202case vmIntrinsics::_getCharUnaligned:203case vmIntrinsics::_getIntUnaligned:204case vmIntrinsics::_getLongUnaligned:205case vmIntrinsics::_putShortUnaligned:206case vmIntrinsics::_putCharUnaligned:207case vmIntrinsics::_putIntUnaligned:208case vmIntrinsics::_putLongUnaligned:209case vmIntrinsics::_checkIndex:210case vmIntrinsics::_updateCRC32:211case vmIntrinsics::_updateBytesCRC32:212case vmIntrinsics::_updateByteBufferCRC32:213#if defined(S390) || defined(PPC64) || defined(AARCH64)214case vmIntrinsics::_updateBytesCRC32C:215case vmIntrinsics::_updateDirectByteBufferCRC32C:216#endif217case vmIntrinsics::_vectorizedMismatch:218case vmIntrinsics::_compareAndSetInt:219case vmIntrinsics::_compareAndSetReference:220case vmIntrinsics::_getCharStringU:221case vmIntrinsics::_putCharStringU:222#ifdef JFR_HAVE_INTRINSICS223case vmIntrinsics::_counterTime:224case vmIntrinsics::_getEventWriter:225#endif226case vmIntrinsics::_getObjectSize:227break;228case vmIntrinsics::_blackhole:229break;230default:231return false; // Intrinsics not on the previous list are not available.232}233234return true;235}236237void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci, bool install_code, DirectiveSet* directive) {238BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();239assert(buffer_blob != NULL, "Must exist");240// invoke compilation241{242// We are nested here because we need for the destructor243// of Compilation to occur before we release the any244// competing compiler thread245ResourceMark rm;246Compilation c(this, env, method, entry_bci, buffer_blob, install_code, directive);247}248}249250251void Compiler::print_timers() {252Compilation::print_timers();253}254255256