001/* 002 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.meta; 024 025import java.util.*; 026import java.util.function.*; 027 028/** 029 * An object that can be assigned a globally unique identifier for use as a key in a 030 * {@link MethodIdMap}. 031 */ 032public interface MethodIdHolder { 033 /** 034 * Sets the unique, positive, non-zero identifier for this method. 035 */ 036 void setMethodId(int id); 037 038 /** 039 * Gets the identifier set by {@link #setMethodId(int)} or 0 if no identifier was assigned to 040 * this method. 041 */ 042 int getMethodId(); 043 044 /** 045 * A singleton class for allocating globally unique method identifiers. 046 */ 047 static final class MethodIdAllocator { 048 049 /** 050 * Ensures a given method has a unique identifier. 051 */ 052 public int assignId(MethodIdHolder holder) { 053 assert Thread.holdsLock(instance) : "must only be called from within MethodIdHolder.allocateIds"; 054 int id = holder.getMethodId(); 055 if (id == 0) { 056 id = nextId++; 057 holder.setMethodId(id); 058 if (idVerifierMap != null) { 059 idVerifierMap.put(holder, id); 060 } 061 } else { 062 assert !idVerifierMap.containsKey(holder) || idVerifierMap.get(holder) == id; 063 } 064 return id; 065 } 066 067 private int nextId = 1; 068 private final Map<MethodIdHolder, Integer> idVerifierMap; 069 070 @SuppressWarnings("all") 071 private MethodIdAllocator() { 072 boolean assertionsEnabled = false; 073 assert assertionsEnabled = true; 074 idVerifierMap = assertionsEnabled ? new HashMap<>() : null; 075 } 076 077 /** 078 * Singleton instance. 079 */ 080 private static final MethodIdAllocator instance = new MethodIdAllocator(); 081 } 082 083 /** 084 * Executes some given code that ensures some set of {@link ResolvedJavaMethod}s have unique ids 085 * {@linkplain MethodIdHolder#setMethodId(int) assigned} to them. The 086 * {@link Consumer#accept(Object)} method of the given object is called under a global lock. 087 */ 088 static void assignIds(Consumer<MethodIdAllocator> methodIdConsumer) { 089 synchronized (MethodIdAllocator.instance) { 090 methodIdConsumer.accept(MethodIdAllocator.instance); 091 } 092 } 093}