synchronized method

This commit is contained in:
Alex Tkachman
2011-12-19 10:21:17 +02:00
parent 9a7d947899
commit 1e471aa9c4
7 changed files with 78 additions and 1 deletions
@@ -1403,7 +1403,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return mask;
}
private int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
public int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
if(resolvedCall != null) {
return pushMethodArguments(resolvedCall, valueParameterTypes);
@@ -20,6 +20,7 @@ import java.util.*;
/**
* @author yole
* @author alex.tkachman
*/
public class IntrinsicMethods {
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
@@ -89,6 +90,7 @@ public class IntrinsicMethods {
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
declareOverload(myStdLib.getLibraryScope().getFunctions("sure"), 0, new Sure());
declareOverload(myStdLib.getLibraryScope().getFunctions("synchronized"), 1, new StupidSync());
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
@@ -0,0 +1,26 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.Arrays;
import java.util.List;
public class StupidSync implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver) {
receiver.put(receiver.type, v);
codegen.pushMethodArguments((JetCallExpression)element, Arrays.asList(JetTypeMapper.TYPE_FUNCTION0));
v.invokestatic("jet/runtime/Intrinsics", "stupidSync", "(Ljava/lang/Object;Ljet/Function0;)Ljava/lang/Object;");
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v);
return StackValue.onStack(expectedType);
}
}
+2
View File
@@ -34,6 +34,8 @@ namespace io {
fun readLine() : String?
}
fun <R> Any.synchronized(block : fun() : R) : R
fun Any?.identityEquals(other : Any?) : Boolean // = this === other
// Can't write a body due to a bootstrapping problem (see JET-74)
@@ -0,0 +1,33 @@
import java.util.concurrent.*
import java.util.concurrent.atomic.*
fun thread(block: fun():Unit ) {
val thread = object: Thread() {
override fun run() {
block()
}
}
thread.start()
}
fun box() : String {
val ref = AtomicInteger()
val cdl = CountDownLatch(11)
for(i in 0..10) {
thread {
var current = 0
do {
current = ref.synchronized {
val v = ref.get() + 1
if(v < 100)
ref.set(v+1)
v
}
}
while(current < 100)
cdl.countDown()
}
}
cdl.await()
return if(ref.get() == 100) "OK" else ref.get().toString()
}
@@ -238,6 +238,12 @@ public class ControlStructuresTest extends CodegenTestCase {
public void testQuicksort() throws Exception {
blackBoxFile("controlStructures/quicksort.jet");
// System.out.println(generateToText());
}
public void testSynchronized() throws Exception {
createEnvironmentWithFullJdk();
blackBoxFile("controlStructures/sync.jet");
// System.out.println(generateToText());
}
}
+8
View File
@@ -1,5 +1,7 @@
package jet.runtime;
import jet.Function0;
import java.util.ArrayList;
/**
@@ -29,6 +31,12 @@ public class Intrinsics {
return (thisVal == anotherVal ? 0 : (anotherVal ? 1 : -1));
}
public static <R> R stupidSync(Object lock, Function0<R> block) {
synchronized (lock) {
return block.invoke();
}
}
private static Throwable sanitizeStackTrace(Throwable throwable) {
StackTraceElement[] stackTrace = throwable.getStackTrace();
ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();