Advertisement
Guest User

Untitled

a guest
Oct 28th, 2014
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.52 KB | None | 0 0
  1. From 53891afeffac045a1467308e598ce3fc8b758647 Mon Sep 17 00:00:00 2001
  2. From: Petka Antonov <p.antonov@partner.samsung.com>
  3. Date: Tue, 28 Oct 2014 14:44:40 +0200
  4. Subject: [PATCH] The patch 2
  5.  
  6. ---
  7.  src/hydrogen.cc                                |  76 ++++++++++--
  8.  src/hydrogen.h                                 |   2 +
  9.  src/objects.h                                  |   1 +
  10.  test/mjsunit/compiler/slice-call-arguments.js  | 163 +++++++++++++++++++++++++
  11.  test/mjsunit/compiler/slice-call-arguments2.js |  61 +++++++++
  12.  5 files changed, 295 insertions(+), 8 deletions(-)
  13.  create mode 100644 test/mjsunit/compiler/slice-call-arguments.js
  14.  create mode 100644 test/mjsunit/compiler/slice-call-arguments2.js
  15.  
  16. diff --git a/src/hydrogen.cc b/src/hydrogen.cc
  17. index 7b1e5b1..30b8e29 100644
  18. --- a/src/hydrogen.cc
  19. +++ b/src/hydrogen.cc
  20. @@ -8571,6 +8571,41 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
  21.  }
  22.  
  23.  
  24. +
  25. +bool HOptimizedGraphBuilder::TryInlineBuiltinArgumentsMethod(
  26. +    Handle<JSFunction> function, int args_count_no_receiver) {
  27. +  if (!function->shared()->HasBuiltinFunctionId()) return false;
  28. +
  29. +  HValue* arguments_object_length = NULL;
  30. +  HInstruction* arguments_object_elements = NULL;
  31. +  {
  32. +    NoObservableSideEffectsScope no_effects(this);
  33. +    if (function_state()->outer() == NULL) {
  34. +      arguments_object_elements = Add<HArgumentsElements>(false);
  35. +      arguments_object_length =
  36. +          AddUncasted<HArgumentsLength>(arguments_object_elements);
  37. +    } else {
  38. +      EnsureArgumentsArePushedForAccess();
  39. +      arguments_object_elements = function_state()->arguments_elements();
  40. +      arguments_object_length =
  41. +          AddUncasted<HConstant>(static_cast<int32_t>(
  42. +              environment()->arguments_environment()->parameter_count() - 1));
  43. +    }
  44. +  }
  45. +
  46. +  BuiltinFunctionId id = function->shared()->builtin_function_id();
  47. +  switch (id) {
  48. +    case kArraySlice: {
  49. +      return false;
  50. +    }
  51. +
  52. +    default:
  53. +      break;
  54. +  }
  55. +  return false;
  56. +}
  57. +
  58. +
  59.  bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr,
  60.                                                        HValue* receiver) {
  61.    Handle<JSFunction> function = expr->target();
  62. @@ -8747,9 +8782,26 @@ void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function,
  63.                                                  int arguments_count) {
  64.    Handle<JSFunction> known_function;
  65.    int args_count_no_receiver = arguments_count - 1;
  66. +  HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver);
  67. +
  68.    if (function->IsConstant() &&
  69.        HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
  70. -    HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver);
  71. +    known_function =
  72. +        Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate()));
  73. +    if (receiver->CheckFlag(HValue::kIsArguments)) {
  74. +      if (TryInlineBuiltinArgumentsMethod(known_function,
  75. +                                          args_count_no_receiver)) {
  76. +        if (FLAG_trace_inlining) {
  77. +          PrintF("Inlining builtin ");
  78. +          known_function->ShortPrint();
  79. +          PrintF("\n");
  80. +        }
  81. +      } else {
  82. +        Bailout(kBadValueContextForArgumentsValue);
  83. +      }
  84. +      return;
  85. +    }
  86. +
  87.      Handle<Map> receiver_map;
  88.      if (receiver->IsConstant() &&
  89.          HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) {
  90. @@ -8758,8 +8810,6 @@ void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function,
  91.                       HConstant::cast(receiver)->handle(isolate()))->map());
  92.      }
  93.  
  94. -    known_function =
  95. -        Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate()));
  96.      if (TryInlineBuiltinMethodCall(expr, known_function, receiver_map,
  97.                                     args_count_no_receiver)) {
  98.        if (FLAG_trace_inlining) {
  99. @@ -8775,6 +8825,10 @@ void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function,
  100.      }
  101.    }
  102.  
  103. +  if (receiver->CheckFlag(HValue::kIsArguments)) {
  104. +    return Bailout(kBadValueContextForArgumentsValue);
  105. +  }
  106. +
  107.    PushArgumentsFromEnvironment(arguments_count);
  108.    HInvokeFunction* call =
  109.        New<HInvokeFunction>(function, known_function, arguments_count);
  110. @@ -8865,21 +8919,27 @@ void HOptimizedGraphBuilder::BuildFunctionCall(Call* expr) {
  111.    Handle<Map> function_map = expr->GetReceiverTypes()->first();
  112.    HValue* checked_function = AddCheckMap(function, function_map);
  113.  
  114. +  DCHECK(expr->arguments()->length() > 0);
  115.    // f and call are on the stack in the unoptimized code
  116.    // during evaluation of the arguments.
  117. -  CHECK_ALIVE(VisitExpressions(expr->arguments()));
  118. +  // Allow 'arguments' reference as receiver for now, it will be checked later.
  119. +  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0), ARGUMENTS_ALLOWED));
  120. +  for (int i = 1; i < expr->arguments()->length(); ++i) {
  121. +    CHECK_ALIVE(VisitForValue(expr->arguments()->at(i)));
  122. +  }
  123.  
  124.    int args_length = expr->arguments()->length();
  125.    int receiver_index = args_length - 1;
  126. +  HValue* receiver = environment()->ExpressionStackAt(receiver_index);
  127.    // Patch the receiver.
  128. -  HValue* receiver = BuildWrapReceiver(
  129. -      environment()->ExpressionStackAt(receiver_index), checked_function);
  130. -  environment()->SetExpressionStackAt(receiver_index, receiver);
  131. +  if (!receiver->CheckFlag(HValue::kIsArguments)) {
  132. +    receiver = BuildWrapReceiver(receiver, checked_function);
  133. +    environment()->SetExpressionStackAt(receiver_index, receiver);
  134. +  }
  135.  
  136.    // Call must not be on the stack from now on.
  137.    int call_index = args_length + 1;
  138.    environment()->RemoveExpressionStackAt(call_index);
  139. -
  140.    HandleIndirectCall(expr, function, args_length);
  141.  }
  142.  
  143. diff --git a/src/hydrogen.h b/src/hydrogen.h
  144. index 9e3601a..15a78a1 100644
  145. --- a/src/hydrogen.h
  146. +++ b/src/hydrogen.h
  147. @@ -2359,6 +2359,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
  148.    bool TryInlineBuiltinMethodCall(Call* expr, Handle<JSFunction> function,
  149.                                    Handle<Map> receiver_map,
  150.                                    int args_count_no_receiver);
  151. +  bool TryInlineBuiltinArgumentsMethod(Handle<JSFunction> function,
  152. +                                       int args_count_no_receiver);
  153.    bool TryInlineBuiltinFunctionCall(Call* expr);
  154.    enum ApiCallType {
  155.      kCallApiFunction,
  156. diff --git a/src/objects.h b/src/objects.h
  157. index 0dc5e3a..f137575 100644
  158. --- a/src/objects.h
  159. +++ b/src/objects.h
  160. @@ -6570,6 +6570,7 @@ class Script: public Struct {
  161.    V(Array.prototype, push, ArrayPush)               \
  162.    V(Array.prototype, pop, ArrayPop)                 \
  163.    V(Array.prototype, shift, ArrayShift)             \
  164. +  V(Array.prototype, slice, ArraySlice)             \
  165.    V(Function.prototype, apply, FunctionApply)       \
  166.    V(Function.prototype, call, FunctionCall)         \
  167.    V(String.prototype, charCodeAt, StringCharCodeAt) \
  168. diff --git a/test/mjsunit/compiler/slice-call-arguments.js b/test/mjsunit/compiler/slice-call-arguments.js
  169. new file mode 100644
  170. index 0000000..708b689
  171. --- /dev/null
  172. +++ b/test/mjsunit/compiler/slice-call-arguments.js
  173. @@ -0,0 +1,163 @@
  174. +// Copyright 2014 the V8 project authors. All rights reserved.
  175. +// Redistribution and use in source and binary forms, with or without
  176. +// modification, are permitted provided that the following conditions are
  177. +// met:
  178. +//
  179. +//   * Redistributions of source code must retain the above copyright
  180. +//     notice, this list of conditions and the following disclaimer.
  181. +//   * Redistributions in binary form must reproduce the above
  182. +//     copyright notice, this list of conditions and the following
  183. +//     disclaimer in the documentation and/or other materials provided
  184. +//     with the distribution.
  185. +//   * Neither the name of Google Inc. nor the names of its
  186. +//     contributors may be used to endorse or promote products derived
  187. +//     from this software without specific prior written permission.
  188. +//
  189. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  190. +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  191. +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  192. +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  193. +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  194. +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  195. +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  196. +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  197. +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  198. +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  199. +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  200. +
  201. +// Flags: --allow-natives-syntax --noalways-opt
  202. +
  203. +function makeCopier(lower, upper) {
  204. +  switch (arguments.length) {
  205. +    case 2:
  206. +      var ret = new Function(
  207. +        "return [].slice.call(arguments, lower, upper);"
  208. +          .replace("lower", lower)
  209. +          .replace("upper", upper));
  210. +      ret.lower = lower;
  211. +      ret.upper = upper;
  212. +      return ret;
  213. +    case 1:
  214. +      var ret = new Function(
  215. +        "return [].slice.call(arguments, lower);"
  216. +          .replace("lower", lower));
  217. +      ret.lower = lower;
  218. +      return ret;
  219. +  }
  220. +}
  221. +
  222. +function verify(fn, args) {
  223. +  fn(); fn();
  224. +  %OptimizeFunctionOnNextCall(fn);
  225. +  fn();
  226. +  fn();
  227. +  assertOptimized(fn);
  228. +  assertArrayEquals(fn(), []);
  229. +  var returned_value = fn.apply(void 0, args);
  230. +  var lower = fn.lower;
  231. +  var upper = fn.upper;
  232. +  var expected = args.slice(lower, upper);
  233. +  assertOptimized(fn);
  234. +  assertTrue(Array.isArray(returned_value));
  235. +  assertArrayEquals(expected, returned_value);
  236. +}
  237. +
  238. +function plainCopy() {
  239. +  return Array.prototype.slice.call(arguments);
  240. +}
  241. +
  242. +verify(plainCopy, [1,2,3]);
  243. +verify(plainCopy, []);
  244. +
  245. +var arr = [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3];
  246. +verify(makeCopier(-1), arr);
  247. +verify(makeCopier(1), arr);
  248. +verify(makeCopier(-4, -10), arr);
  249. +verify(makeCopier(3, -2), arr);
  250. +verify(makeCopier(-5), arr);
  251. +verify(makeCopier(3, -1), arr);
  252. +verify(makeCopier(0, 0), arr);
  253. +verify(makeCopier(1, 0), arr);
  254. +verify(makeCopier(0, 1), arr);
  255. +verify(makeCopier(-1, 1), arr);
  256. +verify(makeCopier(-100), arr);
  257. +verify(makeCopier(-100, -100), arr);
  258. +verify(makeCopier(-10, -5), arr);
  259. +verify(makeCopier(10, -5), arr);
  260. +verify(makeCopier(-123, 72), arr);
  261. +verify(makeCopier(-1, -1), arr);
  262. +verify(makeCopier(3, -1), arr);
  263. +
  264. +var arr = [1, 2, 3];
  265. +
  266. +verify(makeCopier(-1), arr);
  267. +verify(makeCopier(1), arr);
  268. +verify(makeCopier(-4, -10), arr);
  269. +verify(makeCopier(3, -2), arr);
  270. +verify(makeCopier(-5), arr);
  271. +verify(makeCopier(3, -1), arr);
  272. +verify(makeCopier(0, 0), arr);
  273. +verify(makeCopier(1, 0), arr);
  274. +verify(makeCopier(0, 1), arr);
  275. +verify(makeCopier(-1, 1), arr);
  276. +verify(makeCopier(-100), arr);
  277. +verify(makeCopier(-100, -100), arr);
  278. +verify(makeCopier(-10, -5), arr);
  279. +verify(makeCopier(10, -5), arr);
  280. +verify(makeCopier(-123, 72), arr);
  281. +verify(makeCopier(-1, -1), arr);
  282. +verify(makeCopier(3, -1), arr);
  283. +
  284. +var arr = [];
  285. +
  286. +verify(makeCopier(-1), arr);
  287. +verify(makeCopier(1), arr);
  288. +verify(makeCopier(-4, -10), arr);
  289. +verify(makeCopier(3, -2), arr);
  290. +verify(makeCopier(-5), arr);
  291. +verify(makeCopier(3, -1), arr);
  292. +verify(makeCopier(0, 0), arr);
  293. +verify(makeCopier(1, 0), arr);
  294. +verify(makeCopier(0, 1), arr);
  295. +verify(makeCopier(-1, 1), arr);
  296. +verify(makeCopier(-100), arr);
  297. +verify(makeCopier(-100, -100), arr);
  298. +verify(makeCopier(-10, -5), arr);
  299. +verify(makeCopier(10, -5), arr);
  300. +verify(makeCopier(-123, 72), arr);
  301. +verify(makeCopier(-1, -1), arr);
  302. +verify(makeCopier(3, -1), arr);
  303. +
  304. +function calls_not_slice() {
  305. +  return Array.prototype.shift.call(arguments);
  306. +}
  307. +
  308. +calls_not_slice();
  309. +calls_not_slice();
  310. +%OptimizeFunctionOnNextCall(calls_not_slice);
  311. +calls_not_slice();
  312. +assertUnoptimized(calls_not_slice);
  313. +calls_not_slice();
  314. +calls_not_slice();
  315. +%OptimizeFunctionOnNextCall(calls_not_slice);
  316. +calls_not_slice();
  317. +assertUnoptimized(calls_not_slice);
  318. +
  319. +function calls_slice_that_changes() {
  320. +  return Array.prototype.slice.call(arguments);
  321. +}
  322. +
  323. +calls_slice_that_changes();
  324. +calls_slice_that_changes();
  325. +%OptimizeFunctionOnNextCall(calls_slice_that_changes);
  326. +calls_slice_that_changes();
  327. +assertOptimized(calls_slice_that_changes);
  328. +
  329. +Array.prototype.slice = function() {};
  330. +calls_slice_that_changes();
  331. +assertUnoptimized(calls_slice_that_changes);
  332. +calls_slice_that_changes();
  333. +calls_slice_that_changes();
  334. +%OptimizeFunctionOnNextCall(calls_slice_that_changes);
  335. +calls_slice_that_changes();
  336. +assertUnoptimized(calls_slice_that_changes);
  337. diff --git a/test/mjsunit/compiler/slice-call-arguments2.js b/test/mjsunit/compiler/slice-call-arguments2.js
  338. new file mode 100644
  339. index 0000000..b670554
  340. --- /dev/null
  341. +++ b/test/mjsunit/compiler/slice-call-arguments2.js
  342. @@ -0,0 +1,61 @@
  343. +// Copyright 2014 the V8 project authors. All rights reserved.
  344. +// Redistribution and use in source and binary forms, with or without
  345. +// modification, are permitted provided that the following conditions are
  346. +// met:
  347. +//
  348. +//   * Redistributions of source code must retain the above copyright
  349. +//     notice, this list of conditions and the following disclaimer.
  350. +//   * Redistributions in binary form must reproduce the above
  351. +//     copyright notice, this list of conditions and the following
  352. +//     disclaimer in the documentation and/or other materials provided
  353. +//     with the distribution.
  354. +//   * Neither the name of Google Inc. nor the names of its
  355. +//     contributors may be used to endorse or promote products derived
  356. +//     from this software without specific prior written permission.
  357. +//
  358. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  359. +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  360. +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  361. +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  362. +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  363. +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  364. +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  365. +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  366. +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  367. +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  368. +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  369. +
  370. +// Flags: --allow-natives-syntax --noalways-opt
  371. +
  372. +function lotsOfArguments() {
  373. +  return Array.prototype.slice.call(arguments);
  374. +}
  375. +
  376. +var arr = new Array(100000);
  377. +for (var i = 0; i < arr.length; ++i) arr[i] = i;
  378. +
  379. +assertArrayEquals([1,2,3], lotsOfArguments(1,2,3));
  380. +assertArrayEquals([1,2,3], lotsOfArguments(1,2,3));
  381. +%OptimizeFunctionOnNextCall(lotsOfArguments);
  382. +assertArrayEquals([1,2,3], lotsOfArguments(1,2,3));
  383. +assertOptimized(lotsOfArguments);
  384. +var result = lotsOfArguments.apply(void 0, arr);
  385. +assertArrayEquals(arr, result);
  386. +assertUnoptimized(lotsOfArguments);
  387. +
  388. +
  389. +var o = {
  390. +  callsInline: function caller() {
  391. +      return this.toBeInlined(1, 2, 3, 4, 5);
  392. +  },
  393. +  toBeInlined: function callee() {
  394. +      return Array.prototype.slice.call(arguments);
  395. +  }
  396. +};
  397. +
  398. +assertArrayEquals([1,2,3,4,5], o.callsInline());
  399. +assertArrayEquals([1,2,3,4,5], o.callsInline());
  400. +%OptimizeFunctionOnNextCall(o.callsInline);
  401. +assertArrayEquals([1,2,3,4,5], o.callsInline());
  402. +assertOptimized(o.callsInline);
  403. +assertArrayEquals([1,2,3,4,5], o.callsInline());
  404. --
  405. 1.9.1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement