1 | /* |
2 | * Copyright (C) 2017 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "MultithreadedMultiVMExecutionTest.h" |
28 | |
29 | #include "InitializeThreading.h" |
30 | #include "JSContextRefPrivate.h" |
31 | #include "JavaScript.h" |
32 | #include "Options.h" |
33 | #include <mutex> |
34 | #include <string> |
35 | #include <thread> |
36 | #include <vector> |
37 | #include <wtf/MainThread.h> |
38 | |
39 | static int failuresFound = 0; |
40 | |
41 | static std::vector<std::thread>& threadsList() |
42 | { |
43 | static std::vector<std::thread>* list; |
44 | static std::once_flag flag; |
45 | std::call_once(flag, [] () { |
46 | list = new std::vector<std::thread>(); |
47 | }); |
48 | return *list; |
49 | } |
50 | |
51 | void startMultithreadedMultiVMExecutionTest() |
52 | { |
53 | WTF::initializeMainThread(); |
54 | JSC::initializeThreading(); |
55 | |
56 | #define CHECK(condition, message) do { \ |
57 | if (!condition) { \ |
58 | printf("FAILED MultithreadedMultiVMExecutionTest: %s\n", message); \ |
59 | failuresFound++; \ |
60 | } \ |
61 | } while (false) |
62 | |
63 | auto task = [&]() { |
64 | int ret = 0; |
65 | std::string scriptString = |
66 | "const AAA = {A:0, B:1, C:2, D:3};" |
67 | "class Preconditions { static checkArgument(e,t) { if (!e) throw t }};" |
68 | "1 + 2" ; |
69 | |
70 | for (int i = 0; i < 1000; ++i) { |
71 | JSClassRef jsClass = JSClassCreate(&kJSClassDefinitionEmpty); |
72 | CHECK(jsClass, "global object class creation" ); |
73 | JSContextGroupRef contextGroup = JSContextGroupCreate(); |
74 | CHECK(contextGroup, "group creation" ); |
75 | JSGlobalContextRef context = JSGlobalContextCreateInGroup(contextGroup, jsClass); |
76 | CHECK(context, "ctx creation" ); |
77 | |
78 | JSStringRef jsScriptString = JSStringCreateWithUTF8CString(scriptString.c_str()); |
79 | CHECK(jsScriptString, "script to jsString" ); |
80 | |
81 | JSValueRef jsScript = JSEvaluateScript(context, jsScriptString, nullptr, nullptr, 0, nullptr); |
82 | CHECK(jsScript, "script eval" ); |
83 | JSStringRelease(jsScriptString); |
84 | |
85 | JSGlobalContextRelease(context); |
86 | JSContextGroupRelease(contextGroup); |
87 | JSClassRelease(jsClass); |
88 | } |
89 | |
90 | return ret; |
91 | }; |
92 | for (int t = 0; t < 8; ++t) |
93 | threadsList().push_back(std::thread(task)); |
94 | } |
95 | |
96 | int finalizeMultithreadedMultiVMExecutionTest() |
97 | { |
98 | auto& threads = threadsList(); |
99 | for (auto& thread : threads) |
100 | thread.join(); |
101 | |
102 | if (failuresFound) |
103 | printf("FAILED MultithreadedMultiVMExecutionTest\n" ); |
104 | return (failuresFound > 0); |
105 | } |
106 | |