You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/01/26 10:05:35 UTC
svn commit: r500190 - in /harmony/enhanced/drlvm/trunk:
src/test/microbenchmark/harmony-2815/ vm/vmcore/include/
vm/vmcore/src/class_support/
vm/vmcore/src/kernel_classes/javasrc/java/security/
vm/vmcore/src/kernel_classes/native/
Author: varlax
Date: Fri Jan 26 01:05:34 2007
New Revision: 500190
URL: http://svn.apache.org/viewvc?view=rev&rev=500190
Log:
Fixed HARMONY-2815 [drlvm][performance] very slow security checks with quadratical dependence on number of stack frames
Tested on Win32, SUSE9@ia32 SUSE9@x64
Added:
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2815/
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2815/SecurityPerfTest.java
harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_security_AccessController.h (with props)
Modified:
harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/security/AccessController.java
harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp
Added: harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2815/SecurityPerfTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2815/SecurityPerfTest.java?view=auto&rev=500190
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2815/SecurityPerfTest.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2815/SecurityPerfTest.java Fri Jan 26 01:05:34 2007
@@ -0,0 +1,41 @@
+import java.security.Security;
+
+/**
+recursive call of run() checks for security permissions
+
+to run it, issue the recursion depth list via command-line parameters like this:
+java SecurityPerfTest 50 100 150 300 350 400 450 500
+
+on Jrockit/ia32 the time spent for each step depends linearly on the number of
+iterations:
+50 107 // this line should be ignored
+100 1
+150 1
+300 3
+350 5
+400 6
+450 7
+500 9
+*/
+public class SecurityPerfTest {
+ public static void main(String[] args) {
+ System.setSecurityManager(new SecurityManager());
+ for (int i = 0; i < args.length; i++ ) {
+ long start_time = System.currentTimeMillis();
+ int amount = Integer.parseInt(args[i]);
+ run(amount);
+ long total_time = System.currentTimeMillis() - start_time;
+ System.out.println(amount + " " + total_time);
+ }
+ }
+
+public static void run(int count) {
+ if ( count < 0 ) {
+ return;
+ }
+
+//System.out.println("Runner: " + count);
+ System.getProperty("os.name");
+ run(count - 1);
+ }
+}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h?view=diff&rev=500190&r1=500189&r2=500190
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h Fri Jan 26 01:05:34 2007
@@ -196,6 +196,9 @@
Class* java_lang_OutOfMemoryError_Class;
Class* java_lang_ThreadDeath_Class;
+ Class* java_security_ProtectionDomain_Class;
+ unsigned Class_domain_field_offset;
+
ObjectHandle java_lang_Object;
ObjectHandle java_lang_OutOfMemoryError;
ObjectHandle java_lang_ThreadDeath;
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp?view=diff&rev=500190&r1=500189&r2=500190
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp Fri Jan 26 01:05:34 2007
@@ -194,6 +194,9 @@
JavaLangString_VTable = NULL;
+ java_security_ProtectionDomain_Class = NULL;
+ Class_domain_field_offset = 0;
+
vm_class_offset = 0;
vm_state = VM_INITIALIZING;
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/security/AccessController.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/security/AccessController.java?view=diff&rev=500190&r1=500189&r2=500190
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/security/AccessController.java (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/security/AccessController.java Fri Jan 26 01:05:34 2007
@@ -14,10 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision: 1.1.2.2.4.3 $
-*/
package java.security;
@@ -26,8 +22,6 @@
import org.apache.harmony.fortress.security.SecurityUtils;
-import org.apache.harmony.vm.VMStack;
-
/**
* @com.intel.drl.spec_ref
*/
@@ -197,50 +191,27 @@
throw new NullPointerException("permission can not be null");
}
- Class[] trace = VMStack.getClasses(-1, true);
-
- // do a quick check: always trust to doSecure_XXX calls from AC
- for (int i = 0; i < trace.length; i++) {
- if (DoSecure.class == trace[i]) {
- return;
- }
- }
- buildContext(trace).checkPermission(perm);
+ getContext().checkPermission(perm);
}
/**
- * @com.intel.drl.spec_ref
+ * Returns array of ProtectionDomains of classes residing
+ * on the stack of the current thread, up to the caller of nearest
+ * privileged frame; reflection frames are skipped.
+ * The returned array is never null and never contains null elements,
+ * meaning that bootstrap classes are effectively ignored.
+ * @see org.apache.harmony.vm.VMStack.getClasses()
*/
- public static AccessControlContext getContext() {
- Class[] trace = VMStack.getClasses(-1, true);
- return buildContext(trace);
- };
-
+ private static native ProtectionDomain[] getStackDomains();
+
/**
- * Builds AccessControllerContext from the passed stack trace, loading
- * inherited context if neccessary. It's taken out as a separate method as
- * both the getContext() and checkPermission() query the stack trace and I
- * want to avoid additional unnecessary trip to VM.
- *
- * @param trace
- * stack trace
- * @return current AccessControllerContext basing on the <code>trace</code>
- * passed
+ * @com.intel.drl.spec_ref
*/
- private static AccessControlContext buildContext(Class[] trace) {
-
- ArrayList<ProtectionDomain> a = new ArrayList<ProtectionDomain>();
- for (int i = 0; i < trace.length; i++) {
- ProtectionDomain pd = DoSecure.doSecure_getProtectionDomain(trace[i]);
-
- if (!a.contains(pd)) { // remove dups
- a.add(pd);
- }
- }
-
- ProtectionDomain[] stack = new ProtectionDomain[a.size()];
- a.toArray(stack);
+ public static AccessControlContext getContext() {
+ // duplicates (if any) will be removed in ACC constructor
+ ProtectionDomain[] stack = getStackDomains();
+
Thread currThread = Thread.currentThread();
if (currThread == null || contexts == null) {
// Big boo time. No need to check anything ?
@@ -265,41 +236,18 @@
if (that != null && that.combiner != null) {
ProtectionDomain[] assigned = null;
- if (that.context != null) {
- if (that.context.length == 0) {
- assigned = new ProtectionDomain[0];
- } else {
+ if (that.context != null && that.context.length != 0) {
assigned = new ProtectionDomain[that.context.length];
System.arraycopy(that.context, 0, assigned, 0,
assigned.length);
- }
}
ProtectionDomain[] allpds = that.combiner.combine(stack, assigned);
+ if (allpds == null) {
+ allpds = new ProtectionDomain[0];
+ }
return new AccessControlContext(allpds, that.combiner);
}
return new AccessControlContext(stack, that);
- }
-
- private static final class DoSecure {
- /**
- * The doSecure_XXX method acts like a doPrivileged() does.<br>
- * The exception is a special processing in the checkPermission() method.
- * doPrivileged() calls always go through the full check with the stack inspection.<br>
- * doSecure_XXX() calls are always trusted as they always get called from AccessController
- * only, and this is quick-checked in the checkPermission() without inspecting the
- * full call chain.<br>
- * There are currently only one doSecure_XXX method - doSecure_getProtectionDomain(Class klass)<br>
- * The reasons why this is done via this specific and not general (like 'doSecure(PrivilegedAction)')
- * method are:<br>
- * 1. I only need this 1 action and I don't need anything more general<br>
- * 2. I do not want to create additional Class-es/Object-s on each checkPermssion/getContext call.
- *
- * @param klass
- * @return klass.getProtectionDomain()
- */
- private static ProtectionDomain doSecure_getProtectionDomain(Class<?> klass) {
- return klass.getProtectionDomain();
- }
}
}
Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_security_AccessController.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_security_AccessController.h?view=auto&rev=500190
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_security_AccessController.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_security_AccessController.h Fri Jan 26 01:05:34 2007
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY INTEL IJH TOOL.
+ * Please be aware that all changes made to this file manually
+ * will be overwritten by the tool if it runs again.
+ */
+
+#include <jni.h>
+
+
+/* Header for class java.security.AccessController */
+
+#ifndef _JAVA_SECURITY_ACCESSCONTROLLER_H
+#define _JAVA_SECURITY_ACCESSCONTROLLER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Method: java.security.AccessController.getStackDomains()[Ljava/security/ProtectionDomain;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_java_security_AccessController_getStackDomains(JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _JAVA_SECURITY_ACCESSCONTROLLER_H */
+
Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_security_AccessController.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp?view=diff&rev=500190&r1=500189&r2=500190
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp Fri Jan 26 01:05:34 2007
@@ -14,10 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
- * @author Euguene Ostrovsky
- * @version $Revision: 1.1.6.6 $
- */
/**
* @file org_apache_harmony_vm_VMStack.cpp
@@ -30,6 +26,8 @@
#define LOG_DOMAIN "kernel.stack"
#include "cxxlog.h"
+#include <vector>
+
#include "open/jthread.h"
#include "stack_trace.h"
#include "jni_direct.h"
@@ -42,6 +40,7 @@
#include "java_lang_VMClassRegistry.h"
#include "org_apache_harmony_vm_VMStack.h"
+#include "java_security_AccessController.h"
/*
* Class: org_apache_harmony_vm_VMStack
@@ -173,6 +172,75 @@
assert(hythread_is_suspend_enabled());
return arr;
}
+
+/*
+* Method: java.security.AccessController.getStackDomains()[Ljava/security/ProtectionDomain;
+*/
+JNIEXPORT jobjectArray JNICALL
+Java_java_security_AccessController_getStackDomains(JNIEnv *jenv, jclass UNREF)
+{
+ assert(hythread_is_suspend_enabled());
+ unsigned size;
+ StackTraceFrame* frames;
+ st_get_trace(get_thread_ptr(), &size, &frames);
+
+ std::vector<jobject> domains = std::vector<jobject>();
+ Global_Env* genv = jni_get_vm_env(jenv);
+
+ unsigned domain_field_offset = genv->Class_domain_field_offset;
+
+ if (domain_field_offset == 0) {
+ // initialize preloaded values
+ genv->java_security_ProtectionDomain_Class = genv->LoadCoreClass("java/security/ProtectionDomain");
+ String* name = genv->string_pool.lookup("domain");
+ String* desc = genv->string_pool.lookup("Ljava/security/ProtectionDomain;");
+ Field* f = genv->JavaLangClass_Class->lookup_field(name, desc);
+ assert(f);
+ domain_field_offset = genv->Class_domain_field_offset = f->get_offset();
+ }
+
+ // The caller of the caller of this method is stored as a first element of the array.
+ // For details look at the org/apache/harmony/vm/VMStack.java file. Thus skipping 2 frames.
+ unsigned s = 2;
+ for (; s < size; s++) {
+ Method_Handle method = frames[s].method;
+
+ if (isReflectionFrame(method, genv))
+ continue;
+
+ if (isPrivilegedFrame(method, genv)) {
+ // find nearest non-reflection frame and finish looping
+ while (++s < size && isReflectionFrame(frames[s].method, genv));
+ TRACE("Privileged frame at " << s << " of " << size);
+ size = s;
+ method = frames[s].method;
+ }
+
+ jobject pd = GetObjectFieldOffset(jenv,
+ struct_Class_to_java_lang_Class_Handle(method->get_class()), domain_field_offset);
+ if (pd) {
+ domains.push_back(pd);
+ }
+ }
+
+ jclass pdc = struct_Class_to_java_lang_Class_Handle(genv->java_security_ProtectionDomain_Class);
+ assert(pdc);
+ size = domains.size();
+ TRACE("Domains on stack: " << size);
+ // create & fill java array
+ jarray arr = jenv->NewObjectArray(size, pdc, NULL);
+ if (arr != NULL) {
+ for (s = 0; s < size; s++) {
+ jenv->SetObjectArrayElement(arr, s, domains[s]);
+ }
+ } else {
+ // OutOfMemoryError
+ assert(exn_raised());
+ }
+ core_free(frames);
+ return arr;
+}
+
/*
* Class: org_apache_harmony_vm_VMStack