[strongtalk] r193 committed - Allow Alien-based callouts to run in parallel to the VM

1 view
Skip to first unread message

codesite...@google.com

unread,
Dec 28, 2009, 1:48:31 PM12/28/09
to strongta...@googlegroups.com
Revision: 193
Author: StephenLRees
Date: Mon Dec 28 10:47:15 2009
Log: Allow Alien-based callouts to run in parallel to the VM
http://code.google.com/p/strongtalk/source/detail?r=193

Modified:
/branches/gcc-linux/build.win32/strongtalk.ncb
/branches/gcc-linux/build.win32/strongtalk.suo
/branches/gcc-linux/test/main/main.cpp
/branches/gcc-linux/test/prims/alienIntegerCallout0Tests.cpp
/branches/gcc-linux/test/prims/alienIntegerCallout1Tests.cpp
/branches/gcc-linux/test/strongtalkrc
/branches/gcc-linux/vm/prims/byteArray_prims.cpp
/branches/gcc-linux/vm/runtime/process.hpp
/branches/gcc-linux/vm/runtime/vframe.cpp

=======================================
--- /branches/gcc-linux/build.win32/strongtalk.ncb Mon Dec 28 10:39:09 2009
+++ /branches/gcc-linux/build.win32/strongtalk.ncb Mon Dec 28 10:47:15 2009
File is too large to display a diff.
=======================================
--- /branches/gcc-linux/build.win32/strongtalk.suo Mon Dec 28 10:39:09 2009
+++ /branches/gcc-linux/build.win32/strongtalk.suo Mon Dec 28 10:47:15 2009
Binary file, no diff available.
=======================================
--- /branches/gcc-linux/test/main/main.cpp Sun Dec 6 13:13:11 2009
+++ /branches/gcc-linux/test/main/main.cpp Mon Dec 28 10:47:15 2009
@@ -1,6 +1,7 @@
#include "incls/_precompiled.incl"
-#include "incls/_shell.cpp.incl"
#include "incls/_delta.cpp.incl"
+#include "incls/_shell.cpp.incl"
+#include "processOop.hpp"
#include "handle.hpp"
#include "testharness.h"
#include <windows.h>
@@ -12,19 +13,24 @@

static Event* done;

+typedef int (*osfn)(void*);
+typedef int (*fn)(DeltaProcess*);
+
// This is a fake DeltaProcess used to run the tests.
// It is there to allow VM operations to be executed on the VMProcess
thread.
class TestDeltaProcess : public DeltaProcess {
private:
static int launch_tests(DeltaProcess *process);
- oop newProcess();
public:
TestDeltaProcess();
+ TestDeltaProcess(fn launchfn);
~TestDeltaProcess();
void addToProcesses();
void removeFromProcesses();
void deoptimized_wrt_marked_nmethods() {}
bool has_stack() const { return false; }
+
+ static int launch_scheduler(DeltaProcess *process);
};

TestDeltaProcess* testProcess = NULL;
@@ -42,7 +48,7 @@
void TestDeltaProcess::removeFromProcesses() {
Processes::remove(this);
}
-oop TestDeltaProcess::newProcess() {
+oop newProcess() {
return Delta::call(Universe::find_global("Process"),
oopFactory::new_symbol("new"));
}

@@ -50,6 +56,7 @@
oop process = newProcess();
assert(process->is_process(), "Should be process");
set_processObj(processOop(process));
+ processOop(process)->set_process(this);
Processes::add(this);
}

@@ -58,11 +65,29 @@
Processes::remove(this);
os::terminate_thread(_thread); // don't want to launch delta!
os::create_thread((int (*)(void*)) &launch_tests, this, &ignore);
+ oop process = newProcess();
+ assert(process->is_process(), "Should be process");
+ set_processObj(processOop(process));
+ processOop(process)->set_process(this);
+}
+TestDeltaProcess::TestDeltaProcess(fn launchfn): DeltaProcess(NULL, NULL) {
+ int ignore;
+ Processes::remove(this);
+ os::terminate_thread(_thread); // don't want to launch delta!
+ os::create_thread((osfn) launchfn, this, &ignore);
+ oop process = newProcess();
+ assert(process->is_process(), "Should be process");
+ set_processObj(processOop(process));
+ processOop(process)->set_process(this);
}

TestDeltaProcess::~TestDeltaProcess() {
set_processObj(processOop(newProcess()));
}
+void setProcessRefs(DeltaProcess* process, processOop processObj) {
+ processObj->set_process(process);
+ process->set_processObj(processObj);
+}
void initializeSmalltalkEnvironment() {
AddTestProcess ap;
PersistentHandle _new(oopFactory::new_symbol("new"));
@@ -71,22 +96,38 @@
PersistentHandle
processorScheduler(Universe::find_global("ProcessorScheduler"));
PersistentHandle smalltalk(Universe::find_global("Smalltalk"));
PersistentHandle
systemInitializer(Universe::find_global("SystemInitializer"));
+ PersistentHandle forSeconds(oopFactory::new_symbol("forSeconds:"));

PersistentHandle processor(Delta::call(processorScheduler.as_oop(),
_new.as_oop()));
+
associationOop processorAssoc =
Universe::find_global_association("Processor");
processorAssoc->set_value(processor.as_oop());

+ DeltaProcess* scheduler = new
TestDeltaProcess(&TestDeltaProcess::launch_scheduler);
+ DeltaProcess::set_scheduler(scheduler);
+
Delta::call(processor.as_oop(), initialize.as_oop());
Delta::call(systemInitializer.as_oop(), runBase.as_oop());
Delta::call(smalltalk.as_oop(), initialize.as_oop());
}
int TestDeltaProcess::launch_tests(DeltaProcess *process) {
process->suspend_at_creation();
+ DeltaProcess::set_active(process);
initializeSmalltalkEnvironment();
TestRegistry::runAndPrint();
os::signal_event(done);
return 0;
}
+// mock scheduler loop to allow test process->scheduler transfers and
returns
+int TestDeltaProcess::launch_scheduler(DeltaProcess *process) {
+ process->suspend_at_creation();
+ DeltaProcess::set_active(process);
+ while(true) {
+ if (DeltaProcess::wait_for_async_dll(10))
+ process->transfer_to(testProcess);
+ }
+ return 0;
+}
static int vmLoopLauncher(DeltaProcess* testProcess) {
vmProcess->transfer_to(testProcess);
vmProcess->loop();
@@ -95,14 +136,13 @@
void start_vm_process(TestDeltaProcess* testProcess) {
int threadId;
vmProcess = new VMProcess();
+ DeltaProcess::initialize_async_dll_event();
vmThread = os::create_thread((int(*)(void*))&vmLoopLauncher,
testProcess, &threadId);
::testProcess = testProcess;
}
void stop_vm_process() {
os::terminate_thread(vmThread);
}
-
-static __declspec( thread ) int val1;

int main(int argc, char* argv[]) {
parse_arguments(argc, argv);
=======================================
--- /branches/gcc-linux/test/prims/alienIntegerCallout0Tests.cpp Sun Sep 13
14:52:44 2009
+++ /branches/gcc-linux/test/prims/alienIntegerCallout0Tests.cpp Mon Dec 28
10:47:15 2009
@@ -3,6 +3,7 @@
#include "test.h"
#include "delta.hpp"
#include "testUtils.hpp"
+#include "testProcess.hpp"
#include <time.h>

using namespace easyunit;
=======================================
--- /branches/gcc-linux/test/prims/alienIntegerCallout1Tests.cpp Sun Sep 13
14:52:44 2009
+++ /branches/gcc-linux/test/prims/alienIntegerCallout1Tests.cpp Mon Dec 28
10:47:15 2009
@@ -110,6 +110,7 @@
allocateAlien(invalidFunctionAlien, 8, 0);
allocateUnsafe(unsafeAlien, unsafeContents);

+
memset(address, 0, 8);
}

=======================================
--- /branches/gcc-linux/test/strongtalkrc Sun Jun 7 15:02:00 2009
+++ /branches/gcc-linux/test/strongtalkrc Mon Dec 28 10:47:15 2009
@@ -1,3 +1,4 @@
+#+BreakAtWarning
+UseRecompilation
-UseInliningDatabase
+EnableTasks
=======================================
--- /branches/gcc-linux/vm/prims/byteArray_prims.cpp Sun Dec 6 13:13:11
2009
+++ /branches/gcc-linux/vm/prims/byteArray_prims.cpp Mon Dec 28 10:47:15
2009
@@ -825,20 +825,24 @@

PRIM_DECL_2(byteArrayPrimitives::alienCallResult0, oop receiver, oop
argument) {
PROLOGUE_2("alienCallResult0", receiver, argument);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResult(argument);

PersistentHandle resultHandle(argument);
call_out_func_0 entry =
call_out_func_0(StubRoutines::alien_call_entry(0));
-
+
+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle));
-
+ DLLs::exit_async_call(&process);
+
return receiver;
}

PRIM_DECL_3(byteArrayPrimitives::alienCallResult1, oop receiver, oop
argument1, oop argument2) {
PROLOGUE_3("alienCallResult1", receiver, argument1, argument2);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResultArgs(argument1);
checkAlienCalloutArg1(argument2);
@@ -846,15 +850,18 @@
PersistentHandle resultHandle(argument1);
call_out_func_1 entry =
call_out_func_1(StubRoutines::alien_call_entry(1));

+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle),
alienArg(argument2));
+ DLLs::exit_async_call(&process);

return receiver;
}

PRIM_DECL_4(byteArrayPrimitives::alienCallResult2, oop receiver, oop
argument1, oop argument2, oop argument3) {
PROLOGUE_4("alienCallResult2", receiver, argument1, argument2,
argument3);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResultArgs(argument1);
checkAlienCalloutArg1(argument2);
@@ -863,16 +870,19 @@
PersistentHandle resultHandle(argument1);
call_out_func_2 entry =
call_out_func_2(StubRoutines::alien_call_entry(2));

+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle),
alienArg(argument2),
alienArg(argument3));
+ DLLs::exit_async_call(&process);

return receiver;
}

PRIM_DECL_5(byteArrayPrimitives::alienCallResult3, oop receiver, oop
argument1, oop argument2, oop argument3, oop argument4) {
PROLOGUE_5("alienCallResult3", receiver, argument1, argument2,
argument3, argument4);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResultArgs(argument1);
checkAlienCalloutArg1(argument2);
@@ -882,11 +892,13 @@
PersistentHandle resultHandle(argument1);
call_out_func_3 entry =
call_out_func_3(StubRoutines::alien_call_entry(3));

+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle),
alienArg(argument2),
alienArg(argument3),
alienArg(argument4));
+ DLLs::exit_async_call(&process);

return receiver;
}
@@ -895,6 +907,7 @@
oop argument3, oop argument4, oop argument5) {
PROLOGUE_6("alienCallResult4", receiver, argument1, argument2,
argument3, argument4,
argument5);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResultArgs(argument1);
checkAlienCalloutArg1(argument2);
@@ -905,12 +918,14 @@
PersistentHandle resultHandle(argument1);
call_out_func_4 entry =
call_out_func_4(StubRoutines::alien_call_entry(4));

+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle),
alienArg(argument2),
alienArg(argument3),
alienArg(argument4),
alienArg(argument5));
+ DLLs::exit_async_call(&process);

return receiver;
}
@@ -919,6 +934,7 @@
oop argument3, oop argument4, oop argument5, oop argument6) {
PROLOGUE_7("alienCallResult5", receiver, argument1, argument2,
argument3, argument4,
argument5, argument6);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResultArgs(argument1);
checkAlienCalloutArg1(argument2);
@@ -930,6 +946,7 @@
PersistentHandle resultHandle(argument1);
call_out_func_5 entry =
call_out_func_5(StubRoutines::alien_call_entry(5));

+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle),
alienArg(argument2),
@@ -937,6 +954,7 @@
alienArg(argument4),
alienArg(argument5),
alienArg(argument6));
+ DLLs::exit_async_call(&process);

return receiver;
}
@@ -945,6 +963,7 @@
oop argument3, oop argument4, oop argument5, oop argument6,
oop argument7) {
PROLOGUE_8("alienCallResult6", receiver, argument1, argument2,
argument3, argument4,
argument5, argument6, argument7);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResultArgs(argument1);
checkAlienCalloutArg1(argument2);
@@ -957,6 +976,7 @@
PersistentHandle resultHandle(argument1);
call_out_func_6 entry =
call_out_func_6(StubRoutines::alien_call_entry(6));

+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle),
alienArg(argument2),
@@ -965,6 +985,7 @@
alienArg(argument5),
alienArg(argument6),
alienArg(argument7));
+ DLLs::exit_async_call(&process);

return receiver;
}
@@ -972,6 +993,7 @@
oop argument3, oop argument4, oop argument5, oop argument6, oop
argument7, oop argument8) {
PROLOGUE_9("alienCallResult7", receiver, argument1, argument2,
argument3, argument4,
argument5, argument6, argument7, argument8);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResultArgs(argument1);
checkAlienCalloutArg1(argument2);
@@ -985,6 +1007,7 @@
PersistentHandle resultHandle(argument1);
call_out_func_7 entry =
call_out_func_7(StubRoutines::alien_call_entry(7));

+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle),
alienArg(argument2),
@@ -994,12 +1017,14 @@
alienArg(argument6),
alienArg(argument7),
alienArg(argument8));
+ DLLs::exit_async_call(&process);

return receiver;
}

PRIM_DECL_3(byteArrayPrimitives::alienCallResultWithArguments, oop
receiver, oop argument1, oop argument2) {
PROLOGUE_3("alienCallResultWithArguments", receiver, argument1,
argument2);
+ DeltaProcess* process;
checkAlienCalloutReceiver(receiver);
checkAlienCalloutResultArgs(argument1);

@@ -1010,10 +1035,12 @@
PersistentHandle resultHandle(argument1);
call_out_func_args entry =
call_out_func_args(StubRoutines::alien_call_with_args_entry());

+ DLLs::enter_async_call(&process);
entry(alienAddress(receiver),
alienResult(resultHandle),
as_smiOop(length),
objArrayOop(argument2)->objs(1));
+ DLLs::exit_async_call(&process);

return receiver;
}
=======================================
--- /branches/gcc-linux/vm/runtime/process.hpp Tue Jun 9 23:05:09 2009
+++ /branches/gcc-linux/vm/runtime/process.hpp Mon Dec 28 10:47:15 2009
@@ -372,7 +372,12 @@
static DeltaProcess* _scheduler_process;
static bool _is_idle;

- // sets the active process
+ // The launch function for a new thread
+ static int launch_delta(DeltaProcess* process);
+
+ public:
+
+ // sets the active process (note: public only to support testing)
static void set_active(DeltaProcess* p) {
_active_delta_process = p;
if (_active_delta_process->state() != uncommon) {
@@ -382,11 +387,6 @@

// sets the scheduler process
static void set_scheduler(DeltaProcess* p) { _scheduler_process = p; }
-
- // The launch function for a new thread
- static int launch_delta(DeltaProcess* process);
-
- public:

// returns the active delta process
static DeltaProcess* active() { return _active_delta_process; }
=======================================
--- /branches/gcc-linux/vm/runtime/vframe.cpp Sun Jun 7 11:33:29 2009
+++ /branches/gcc-linux/vm/runtime/vframe.cpp Mon Dec 28 10:47:15 2009
@@ -609,6 +609,10 @@
// This scope does not allocate an interpreter contextOop
if (scope->isMethodScope()) return NULL;

+ if (!scope->method()->expectsContext() &&
+ scope->method()->parent()->allocatesInterpretedContext()) {
+ warning("May be allocating context when unneeded");
+ }
return compute_canonical_parent_context(scope, vf, con);
}

Reply all
Reply to author
Forward
0 new messages