mini_racer 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7469d9f13294a9088aaf40f823c0d027a9f50bf6
4
- data.tar.gz: b34b103238ba3f509a3b46382b62ba6f9f2b8500
3
+ metadata.gz: bcbf79004383ed09c2b2ceb6821a13a01ef11c36
4
+ data.tar.gz: d18d5d701d8067a011f2e778c257a076036cb029
5
5
  SHA512:
6
- metadata.gz: 134198f0aae35ca62a8c2f7e2d083c9ca7c8cc0a07568039b60953dc0c65957118023a56e4d7c97acde43f6951cd83f79aaa1684fc4178ae9314e4d0811e2614
7
- data.tar.gz: cb287c13bdd6ca8d0f8ecc738d8cb97d75b609973e19e5529dd39c5afa2dc425f1416532694e5aeab66df6b5667f99f3df1f723ed004d37c1cd150d344d45ccb
6
+ metadata.gz: fa133304bbbbac7c0a7cd205d19928cc0bfd074a340c0ef18ceef92bff9bc4e3ff4924085c418ee32e14663c84c856837f7f745b09db65d5ecd89241b5081689
7
+ data.tar.gz: 9bbfa1a279aef49bcfe500583b73796c4766bc5bbbd278f1d3c76bdf8c9ce2df67d292f2c1e25d94e739f532f252356497b7e4d43dc94fab9c0e8d0819b2cd09
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 09-03-2017
2
+
3
+ - 0.1.9
4
+
5
+ - Perf: speed up ruby/node boundary performance when moving large objects
6
+
1
7
  06-02-2017
2
8
 
3
9
  - 0.1.8
data/README.md CHANGED
@@ -232,22 +232,31 @@ The `bench` folder contains benchmark.
232
232
 
233
233
  ### Benchmark minification of Discourse application.js (both minified and unminified)
234
234
 
235
- - MiniRacer version 0.1
235
+ MiniRacer outperforms node when minifying assets via execjs.
236
+
237
+ - MiniRacer version 0.1.9
238
+ - node version 6.10
236
239
  - therubyracer version 0.12.2
237
240
 
238
- ```
239
- $ ruby bench_uglify.rb
240
- Benching with MiniRacer
241
- MiniRacer minify discourse_app.js 13813.36ms
242
- MiniRacer minify discourse_app_minified.js 18271.19ms
243
- MiniRacer minify discourse_app.js twice (2 threads) 13587.21ms
244
241
  ```
245
242
 
246
- ```
243
+ $ bundle exec ruby bench.rb mini_racer
244
+ Benching with mini_racer
245
+ mini_racer minify discourse_app.js 9292.72063ms
246
+ mini_racer minify discourse_app_minified.js 11799.850171ms
247
+ mini_racer minify discourse_app.js twice (2 threads) 10269.570797ms
248
+
249
+ sam@ubuntu exec_js_uglify % bundle exec ruby bench.rb node
250
+ Benching with node
251
+ node minify discourse_app.js 13302.715484ms
252
+ node minify discourse_app_minified.js 18100.761243ms
253
+ node minify discourse_app.js twice (2 threads) 14383.600207000001ms
254
+
255
+ sam@ubuntu exec_js_uglify % bundle exec ruby bench.rb therubyracer
247
256
  Benching with therubyracer
248
- MiniRacer minify discourse_app.js 151467.164ms
249
- MiniRacer minify discourse_app_minified.js 158172.097ms
250
- MiniRacer minify discourse_app.js twice (2 threads) - DOES NOT FINISH
257
+ therubyracer minify discourse_app.js 171683.01867700001ms
258
+ therubyracer minify discourse_app_minified.js 143138.88492ms
259
+ therubyracer minify discourse_app.js twice (2 threads) NEVER FINISH
251
260
 
252
261
  Killed: 9
253
262
  ```
@@ -256,6 +265,8 @@ The huge performance disparity (MiniRacer is 10x faster) is due to MiniRacer run
256
265
 
257
266
  Note how the global interpreter lock release leads to 2 threads doing the same work taking the same wall time as 1 thread.
258
267
 
268
+ As a rule MiniRacer strives to always support and depend on the latest stable version of libv8.
269
+
259
270
  ## Installation
260
271
 
261
272
  Add this line to your application's Gemfile:
@@ -50,6 +50,7 @@ typedef struct {
50
50
  bool parsed;
51
51
  bool executed;
52
52
  bool terminated;
53
+ bool json;
53
54
  Persistent<Value>* value;
54
55
  Persistent<Value>* message;
55
56
  Persistent<Value>* backtrace;
@@ -68,6 +69,7 @@ static VALUE rb_eScriptRuntimeError;
68
69
  static VALUE rb_cJavaScriptFunction;
69
70
  static VALUE rb_eSnapshotError;
70
71
  static VALUE rb_ePlatformAlreadyInitializedError;
72
+ static VALUE rb_mJSON;
71
73
 
72
74
  static VALUE rb_cFailedV8Conversion;
73
75
  static VALUE rb_cDateTime = Qnil;
@@ -118,11 +120,10 @@ nogvl_context_eval(void* arg) {
118
120
  EvalParams* eval_params = (EvalParams*)arg;
119
121
  EvalResult* result = eval_params->result;
120
122
  Isolate* isolate = eval_params->context_info->isolate_info->isolate;
123
+
121
124
  Isolate::Scope isolate_scope(isolate);
122
125
  HandleScope handle_scope(isolate);
123
-
124
126
  TryCatch trycatch(isolate);
125
-
126
127
  Local<Context> context = eval_params->context_info->context->Get(isolate);
127
128
  Context::Scope context_scope(context);
128
129
 
@@ -135,6 +136,7 @@ nogvl_context_eval(void* arg) {
135
136
  result->parsed = !parsed_script.IsEmpty();
136
137
  result->executed = false;
137
138
  result->terminated = false;
139
+ result->json = false;
138
140
  result->value = NULL;
139
141
 
140
142
  if (!result->parsed) {
@@ -147,9 +149,36 @@ nogvl_context_eval(void* arg) {
147
149
  result->executed = !maybe_value.IsEmpty();
148
150
 
149
151
  if (result->executed) {
150
- Persistent<Value>* persistent = new Persistent<Value>();
151
- persistent->Reset(isolate, maybe_value.ToLocalChecked());
152
- result->value = persistent;
152
+
153
+ // arrays and objects get converted to json
154
+ Local<Value> local_value = maybe_value.ToLocalChecked();
155
+ if ((local_value->IsObject() || local_value->IsArray()) &&
156
+ !local_value->IsDate() && !local_value->IsFunction()) {
157
+ Local<Object> JSON = context->Global()->Get(
158
+ String::NewFromUtf8(isolate, "JSON"))->ToObject();
159
+
160
+ Local<Function> stringify = JSON->Get(v8::String::NewFromUtf8(isolate, "stringify"))
161
+ .As<Function>();
162
+
163
+ Local<Object> object = local_value->ToObject();
164
+ const unsigned argc = 1;
165
+ Local<Value> argv[argc] = { object };
166
+ MaybeLocal<Value> json = stringify->Call(JSON, argc, argv);
167
+
168
+ if (json.IsEmpty()) {
169
+ result->executed = false;
170
+ } else {
171
+ result->json = true;
172
+ Persistent<Value>* persistent = new Persistent<Value>();
173
+ persistent->Reset(isolate, json.ToLocalChecked());
174
+ result->value = persistent;
175
+ }
176
+
177
+ } else {
178
+ Persistent<Value>* persistent = new Persistent<Value>();
179
+ persistent->Reset(isolate, local_value);
180
+ result->value = persistent;
181
+ }
153
182
  }
154
183
  }
155
184
 
@@ -190,6 +219,7 @@ nogvl_context_eval(void* arg) {
190
219
 
191
220
  static VALUE convert_v8_to_ruby(Isolate* isolate, Handle<Value> &value) {
192
221
 
222
+ Isolate::Scope isolate_scope(isolate);
193
223
  HandleScope scope(isolate);
194
224
 
195
225
  if (value->IsNull() || value->IsUndefined()){
@@ -239,11 +269,10 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Handle<Value> &value) {
239
269
  }
240
270
 
241
271
  if (value->IsObject()) {
242
-
243
- TryCatch trycatch(isolate);
244
-
245
272
  VALUE rb_hash = rb_hash_new();
273
+ TryCatch trycatch(isolate);
246
274
  Local<Context> context = Context::New(isolate);
275
+
247
276
  Local<Object> object = value->ToObject();
248
277
  MaybeLocal<Array> maybe_props = object->GetOwnPropertyNames(context);
249
278
  if (!maybe_props.IsEmpty()) {
@@ -486,8 +515,6 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
486
515
  Data_Get_Struct(self, ContextInfo, context_info);
487
516
  Isolate* isolate = context_info->isolate_info->isolate;
488
517
 
489
-
490
-
491
518
  {
492
519
  Locker lock(isolate);
493
520
  Isolate::Scope isolate_scope(isolate);
@@ -553,14 +580,21 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
553
580
  }
554
581
  }
555
582
 
556
- // New scope for return value, must release GVL which
583
+ // New scope for return value
557
584
  {
558
585
  Locker lock(isolate);
559
586
  Isolate::Scope isolate_scope(isolate);
560
587
  HandleScope handle_scope(isolate);
561
588
 
562
589
  Local<Value> tmp = Local<Value>::New(isolate, *eval_result.value);
563
- result = convert_v8_to_ruby(isolate, tmp);
590
+
591
+ if (eval_result.json) {
592
+ Local<String> rstr = tmp->ToString();
593
+ VALUE json_string = rb_enc_str_new(*String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
594
+ result = rb_funcall(rb_mJSON, rb_intern("parse"), 1, json_string);
595
+ } else {
596
+ result = convert_v8_to_ruby(isolate, tmp);
597
+ }
564
598
 
565
599
  eval_result.value->Reset();
566
600
  delete eval_result.value;
@@ -892,6 +926,7 @@ extern "C" {
892
926
  rb_eSnapshotError = rb_define_class_under(rb_mMiniRacer, "SnapshotError", rb_eStandardError);
893
927
  rb_ePlatformAlreadyInitializedError = rb_define_class_under(rb_mMiniRacer, "PlatformAlreadyInitialized", rb_eStandardError);
894
928
  rb_cFailedV8Conversion = rb_define_class_under(rb_mMiniRacer, "FailedV8Conversion", rb_cObject);
929
+ rb_mJSON = rb_define_module("JSON");
895
930
 
896
931
  VALUE rb_cExternalFunction = rb_define_class_under(rb_cContext, "ExternalFunction", rb_cObject);
897
932
  rb_define_method(rb_cContext, "stop", (VALUE(*)(...))&rb_context_stop, 0);
data/lib/mini_racer.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "mini_racer/version"
2
2
  require "mini_racer_extension"
3
3
  require "thread"
4
+ require "json"
4
5
 
5
6
  module MiniRacer
6
7
 
@@ -1,3 +1,3 @@
1
1
  module MiniRacer
2
- VERSION = "0.1.8"
2
+ VERSION = "0.1.9"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_racer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-06 00:00:00.000000000 Z
11
+ date: 2017-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler