Advertisement
Guest User

Untitled

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