All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cz.advel.stack.Stack Maven / Gradle / Ivy

The newest version!
/*
 * JStackAlloc (c) 2008 Martin Dvorak 
 *
 * This software is provided 'as-is', without any express or implied warranty.
 * In no event will the authors be held liable for any damages arising from
 * the use of this software.
 * 
 * Permission is granted to anyone to use this software for any purpose, 
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * 
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 */

package cz.advel.stack;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Support for stack allocation of "value" objects. The only requirements for "value"
 * objects is that they must have public zero argument constructor and set
 * method with one argument of the same type (or superclass) which copies data from
 * given instance.

* * Example usage: *

 * public static Vector3f average(Vector3f v1, Vector3f v2, Vector3f out) {
 *     out.add(v1, v2);
 *     out.scale(0.5f);
 *     return out;
 * }
 * 
 * public static void test() {
 *     Vector3f v1 = Stack.alloc(Vector3f.class);
 *     v1.set(0f, 1f, 2f);
 * 
 *     Vector3f v2 = Stack.alloc(v1);
 *     v2.x = 10f;
 * 
 *     Vector3f avg = average(v1, v2, Stack.alloc(Vector3f.class));
 * }
 * 
* which is transformed into something like the following code. The actual * generated code has mangled names for unique type identification and can have * other minor differences. *
 * public static void test() {
 *     $Stack stack = $Stack.get();
 *     stack.pushVector3f();
 *     try {
 *         Vector3f v1 = stack.getVector3f();
 *         v1.set(0f, 1f, 2f);
 * 
 *         Vector3f v2 = stack.getVector3f(v1);
 *         v2.x = 10f;
 * 
 *         Vector3f avg = average(v1, v2, stack.getVector3f());
 *     }
 *     finally {
 *         stack.popVector3f();
 *     }
 * }
 * 
* * Rules: *
    *
  • classes needs to be instrumented by provided InstrumentationTask for ANT, otherwise * error is throwed in runtime
  • *
  • stack is pushed only once per method, do not use stack allocation in loops
  • *
  • returning of stack allocated objects is not supported, use output parameter instead (like in the * example)
  • *
  • working with stack is thread-safe, the data are separate for each thread
  • *
  • combining different libraries works fine, each must have their stack stored * in different package, so you'll just end up with multiple stacks in final application, * which is fine, because the values are used between them without problem *
  • when creating and destroying threads you must be aware that the implementation * uses ThreadLocal to persist stack instances between method calls, it's advisable * to call cleanCurrentThread method on thread just before destroying *
  • *
* * @author jezek2 */ public class Stack { final private static List> threadLocalList = new ArrayList>(); private Stack() { } /** * Returns stack allocated object.

* * Requires instrumentation of your classes in order to work. * * @param the type of object to allocate * @param cls class type, must be compile-time constant * @return stack allocated instance of given class */ public static T alloc(Class cls) { throw new Error("not instrumented"); } /** * Returns stack allocated object with copied value from given parameter.

* * Requires instrumentation of your classes in order to work. * * @param the type of object to allocate * @param obj object to copy on stack, the type must be statically known * @return stack allocated instance with copied data */ public static T alloc(T obj) { throw new Error("not instrumented"); } /** * Used internally. * * @param local the thread-local data to be registered */ public static synchronized void internalRegisterThreadLocal(ThreadLocal local) { threadLocalList.add(new WeakReference<>(local)); } /** * Removes all cached stack instances for current thread. */ public static synchronized void cleanCurrentThread() { for (Iterator> it = threadLocalList.iterator(); it.hasNext(); ) { WeakReference ref = it.next(); ThreadLocal local = ref.get(); if (local != null) { local.remove(); } else { it.remove(); } } } /** * Removes all cached stack instances for current thread in current library.

* * Requires instrumentation of your classes in order to work. */ public static void libraryCleanCurrentThread() { throw new Error("not instrumented"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy