Locks for compilation state callbacks and for the native module are
again taken one after the other. As a consequence, publishing compiled
Wasm code again happens in parallel. Compile times are now comparable to
before lazy hints were enabled.
Bug: chromium:949050
Change-Id: I45c52254d046de080938bd131fd3ed8116660bef
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1552787
Commit-Queue: Frederik Gossen <frgossen@google.com>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60646}
This reverts commit 1fb26d837f.
Reason for revert: Flushes out TSan issues: https://ci.chromium.org/p/v8/builders/ci/V8%20Linux64%20TSAN/25782
Original change's description:
> [regalloc] Enable control flow aware allocation
>
> This is a test to see how much and where we regress. We have seen
> some quirks of our current allocator that do not show up in this
> new approach, so we need to decide whether to stabilize the new
> allocation scheme. Performance numbers are a key indicator for that
> decision.
>
> This patch is intended to be reverted after stability and performance
> numbers are in (i.e. after a few days).
>
> Change-Id: I8df8ff7de8efa82a8abbdfa1d21d7877756f129e
> Bug: v8:9088
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1552786
> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#60643}
TBR=mstarzinger@chromium.org,jarin@chromium.org,sigurds@chromium.org
Change-Id: Ia1934b01b0909479b2bd52ba686cc9b3fb364b4b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:9088
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1554682
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60645}
This is a test to see how much and where we regress. We have seen
some quirks of our current allocator that do not show up in this
new approach, so we need to decide whether to stabilize the new
allocation scheme. Performance numbers are a key indicator for that
decision.
This patch is intended to be reverted after stability and performance
numbers are in (i.e. after a few days).
Change-Id: I8df8ff7de8efa82a8abbdfa1d21d7877756f129e
Bug: v8:9088
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1552786
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60643}
Some state related to WasmMemories is cached on the JSArrayBuffer
object (is_growable, is_wasm_memory). The problem with this is in
some PostMessage flows, this information can get lost depending on
how JSArrayBuffers are deserialized. In this particular case when
the WasmMemory is postMessaged, it goes through the Blink
DedicatedWorkerMessagingProxy::PostMessageToWorkerGlobalScope flow,
which reconstructs the ArrayBuffer from the backing store, and size,
and loses the is_growable flag, leading to a failure to grow memory.
Moving the is_growable flag so that AllocationData can be the source
of truth for all wasm memory state, and is consistently preserved
across PostMessage.
Change-Id: I775f66ddeff68b8cafc18b75ca5460dfb0343c8b
Bug: v8:9065
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1549789
Commit-Queue: Deepti Gandluri <gdeepti@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60641}
Indexed fields in classes can now be initialized using iterators
and a spread syntax, e.g.:
class Foo {
length: Smi;
elements[length]: Object;
}
new Foo{length: 5, elements: ...iter};
where iter implements Torque's iterator protocol. This protocol
requires the definition of a method with the following signature:
Next(): <type> labels NoMore;
Where <type> is the Torque type of the values to be iterated.
In the case of indexed field initialization, the type must be
the field's type or a subtype thereof.
Field initialization with spread is desugared into a loop that
calls the spread iterator's Next method and assigns each
returned value in order to the corresponding indexed field
element.
The general machinery for the spread syntax has been added to
the ast and parser, however, it can currently only be used in
the specific context of indexed field initialization. Spread
operators used in any other context will cause an error.
Bug: v8:7793
Change-Id: If071e61db8166573c28d13318879c88ba96f6d98
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1550407
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60639}
We only use the safe math helpers (CheckedNumeric<T>) in very few
places. The headers are huge though, and complex. They are pulled in to
839 of our object files, increasing compilation time.
I also find the implicit checks more easy to understand than the complex
logic in CheckedNumeric.
Thus, this CL removes the safe_math headers and implements bounds
checks for the five uses explicitly.
R=jkummerow@chromium.org, mlippautz@chromium.org
Bug: v8:8834
Change-Id: I2d60f95799ee61cfa161354428605f67829cd736
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1547651
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60630}
It's implied by the last clause of the conjunction.
Change-Id: I78a810a259888eda696c77cd6c117b35ef9e861a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1549171
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60627}
Context::microtask_context can be null after v8::Context::DetachGlobal
is called, and that should cancel microtasks that are associated to
the detached context.
However, there are several callers left without the null check to the
microtask queue, and that causes crashes.
This CL adds the null check and cancellation as the crash fix.
Bug: chromium:937784
Change-Id: Ie8d107f28f200cee6e75798e3f72c5ed7a2a461c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1545139
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60623}
This changes the syntax for constructing structs and classes to explicitly
mention the fieldnames, similar to JavaScript object literals.
The fields still have to be listed in the same order as in the struct/class
declaration.
As in Javascript, {foo: foo} can be abbreviated as {foo}.
Example:
macro NewJSArray(implicit context: Context)(
map: Map, elements: FixedArrayBase): JSArray {
return new JSArray{
map,
properties_or_hash: kEmptyFixedArray,
elements,
length: elements.length
};
}
Drive-by cleanup: Make struct and class constructors follow the same pattern
in the parser and the AST.
Bug: v8:9018 v8:7793
Change-Id: I22ff7f68270e4f406aa80731a709d41ea52f52bb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1551999
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60622}
Don't record samples from machines without high-resolution timers,
as that can cause serious reporting issues. See the thread at
http://g/chrome-metrics-team/NwwJEyL8odU/discussion for more details.
Bug: v8:9074
Change-Id: I8f9b588b249f944c4bc95feedf56960b28db9ddc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1552001
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60621}
This is port for https://crrev.com/c/1524482
Original commit message:
This allows immediates to be encoded directly into instructions, rather than
mov-ing constants to registers first.
This patch only changes emit_{i64,i32}_add, other emit_ functions will be changed once
this approach has been approved.
Bug: v8:9038
Change-Id: I96929f870e54b24403a32428f3db31b42f41087a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1545148
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Commit-Queue: Yu Yin <xwafish@gmail.com>
Cr-Commit-Position: refs/heads/master@{#60619}
This reverts commit 42beed975e.
Reason for revert: This commit seems to cause consistent failures in
some ProcessMemoryMetricsEmitterTest tests on Mac and ChromeOS. I'm
not sure what the exact reasoning behind this is. See https://crbug.com/949157.
Original change's description:
> Reland "[ptr-compr][x64] Temporarily enable pointer compression on x64"
>
> This is a reland of 4f051fd5da
>
> Relanding after fixing Chromium issues.
>
> Original change's description:
> > [ptr-compr][x64] Temporarily enable pointer compression on x64
> >
> > ... and make sure that the x64 ptr-compr bots proceed testing V8 without
> > pointer compression in order to keep testing the full pointer mode.
> >
> > Bug: v8:7703
> > Cq-Include-Trybots: luci.v8.try:v8_linux64_ubsan_rel_ng,v8_linux64_tsan_rel
> > Change-Id: Iee725deda813425a6f0722948b54976154f50909
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1497139
> > Reviewed-by: Michael Hablich <hablich@chromium.org>
> > Reviewed-by: Michael Achenbach <machenbach@chromium.org>
> > Commit-Queue: Michael Achenbach <machenbach@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#60230}
>
> Bug: v8:7703
> Change-Id: Ic2d1c2ae41ec645f34963f5f561c33199c72ef4b
> Cq-Include-Trybots: luci.v8.try:v8_linux64_ubsan_rel_ng,v8_linux64_tsan_rel
> Cq-Include-Trybots: luci.chromium.try:fuchsia_x64,linux-rel
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1535819
> Commit-Queue: Igor Sheludko <ishell@chromium.org>
> Reviewed-by: Michael Achenbach <machenbach@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#60582}
TBR=machenbach@chromium.org,hablich@chromium.org,leszeks@chromium.org,ishell@chromium.org,verwaest@chromium.org
Change-Id: Ib9737081e90dddcfe44af9da1275a610da209323
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7703
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1550709
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60618}
Just rely on calling toString. This matches other vendor's implementations.
BUG=chromium:948257
R=dgozman@chromium.org
Change-Id: I325a12dd47712263a1ef4deee0bb2de9c4a1c656
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1545124
Reviewed-by: Pavel Feldman <pfeldman@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60617}
Making 43K of room for landing ICU64.
Size Change (on x64.release)
D8 before 23,683,192
D8 after 23,639,296
Reduce 43,896 bytes
Bugs: v8:8348
Change-Id: I057f7d59e955a2e5e017873e5b3b5daf5b142ae2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1478710
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60616}
These tests make sure the ticks are correct when resolving against a
Promise.
Without the optimization, the result is:
"start,tick 1,tick 2,tick 3,tick 4,done,tick 5"
With the optimization, the result is:
"start,tick 1,tick 2,done,tick 3,tick 4,tick 5"
Bug: v8:8267
Change-Id: I6c6499c7c256927531a99bab4ae1c5bd5069ef7c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1534884
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60615}
This is a part of porting Proxy-related builtins to Torque.
Spec: https://tc39.github.io/ecma262/#sec-proxy.revocable
Bug: v8:6664
Change-Id: I5f53eb4dff8ff9d3156b601652f3f86ede25fc1d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1529261
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60613}
Even though both are allowed in the style guide, it recommends to use
'using', as its syntax is more consistent with the rest of C++.
This CL turns all typedefs in interpreter code to 'using' declarations.
R=leszeks@chromium.org
Bug: v8:8834
Change-Id: Ide1e8a35a56a840b36b3ceab1307df1bcab94acd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1545900
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60609}
This CL enables adding code to the top-most {WasmCodeRefScope} when
either adding code to the {NativeModule} (we have a nice choke point
for that in {PublishCodeLocked}), or when looking up existing code from
a {NativeModule}.
It also enables the DCHECK that for each such operation, there must be
an enclosing {WasmCodeRefScope}.
R=titzer@chromium.org
Bug: v8:8217
Change-Id: Ie93ca0b31b1577bef074923b3d228a9f214a909c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1533861
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60608}
When TurboFan optimizes field access, we need to check first that the
runtime already determined the correct field representation properly.
If the field representation is still None, we cannot optimize this in
TurboFan straight away but we have to call the IC to let the runtime
do the magic.
Bug: chromium:944865
Change-Id: I032a48824e83806e1be7670346f518b258a9dd65
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1549167
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60607}
The native flag is a left-over from self-hosted JavaScript. Currently
only the empty function and empty script are marked native.
This CL removes the native flag from the ParseInfo,
UnoptimizedCompilationInfo and its handling in the bytecode generator.
R=leszeks@chromium.org
Bug: v8:8834,v8:9043
Change-Id: I60726e28ce83cc84249e9c49bdc88d81f0a695c9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1545079
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60606}
Using the Isolate's allocator when creating the WasmModule can lead to
use-after-free situations when the NativeModule is shared across
Isolates.
R=mstarzinger@chromium.org
Bug: v8:9079
Change-Id: I5a564852179cc5b9d4cbad2a002d3b6e14b01968
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1550404
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60605}
This adds new timed histograms to measure the time that TurboFan spends
on various compilation phases on a per function bases. This includes the
following new counters:
- V8.TurboFanOptimizePrepare
Time spent in the preparation phase of TurboFan optimization. Recorded
on each regular optimization of a function.
- V8.TurboFanOptimizeExecute
Time spent in the execution phase of TurboFan optimization. Recorded on
each regular optimization of a function.
- V8.TurboFanOptimizeFinalize
Time spent in the finalization phase of TurboFan optimization. Recorded
on each regular optimization of a function.
- V8.TurboFanOptimizeTotalForeground
Total time spent on the main thread during TurboFan optimization.
Recorded on each regular optimization of a function.
- V8.TurboFanOptimizeTotalBackground
Total time spent on a background thread during TurboFan optimization.
Recorded on each regular optimization of a function.
- V8.TurboFanOptimizeTotalTime
Total time from starting optimizing to installing the code object.
Recorded on each regular optimization of a function.
- V8.TurboFanOptimizeForOnStackReplacementPrepare
Time spent in the preparation phase of TurboFan optimization for On
Stack Replacement (OSR). Recorded on each optimization for on-stack
replacement of a function.
- V8.TurboFanOptimizeForOnStackReplacementExecute
Time spent in the execution phase of TurboFan optimization for On Stack
Replacement (OSR). Recorded on each optimization for on-stack replacement
of a function.
- V8.TurboFanOptimizeForOnStackReplacementFinalize
Time spent in the finalization phase of TurboFan optimization for On Stack
Replacement (OSR). Recorded on each optimization for on-stack replacement
of a function.
- V8.TurboFanOptimizeForOnStackReplacementTotalTime
Total time from starting optimizing for On Stack Replacement (OSR) to
installing the code object. Recorded on each optimization for on-stack
replacement of a function.
This should give us a good overview and guide/validate future work on
the concurrent optimization pipeline.
Bug: v8:7790, v8:9074
Change-Id: I96573cd1da472684d06624b7573e4afd6efca99c
Doc: http://doc/1umgFxjLQ9p22lVS_BdhmAlo1o9xnxnWlhVi_HMWNktM
Cq-Include-Trybots: luci.chromium.try:linux-blink-rel
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1547864
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60604}
With lazy feedback allocation we load the interrupt budget from the
ClosureFeedbackCellArray instead of the bytecode array. The factory method
that constructs the ClosureFeedbackCellArray ensures we have a field for
interrupt budget. So, it is safe to omit bounds check here. Including the
bounds check increases the size of all jump bytecode handlers by around
~120 bytes. This translates to ~9-10KB of the native code size on Android.
Bug: chromium:948835
Change-Id: I8e10b3f630097728ae9e520bfb0d85dfc0f806ea
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1550403
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60603}
On arm processors, we need to have some kind of subexpression
elimination running after memory optimizer, so that we reuse index
calculation for loads and stores. This CL introduces a small cleanup
phase after memory optimizer.
Bug: chromium:947225
Change-Id: Ifda7b348d968d58f31947a4ba139863059f4112d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1547664
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60602}
This seals any surrounding {HandleScope} when the interpreter enters the
main interpreter loop. It ensures that there are no accidental leaks of
handles into the surrounding scope and enforces that operations dealing
with handles open their own scope.
R=clemensh@chromium.org
Change-Id: I43d479129bef60beb7565022b24577f8bf1dc522
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1550401
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60601}
Reading --verify_predictable makes me sad, whereas --verify-predictable
makes me happy. This CL introduces more happiness.
R=machenbach@chromium.org
Bug: v8:8834
Change-Id: Id51a75f32e6d5a2f87aed81e058a8b6dff189758
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1550399
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60599}
This adds preliminary support for handling the "br_on_exn" opcode in the
interpreter. It also makes "catch" and "rethrow" use a proper exception
reference instead of a dummy value.
To that end this also adds {Handle<>} as a new kind of {WasmValue} which
is intended to pass reference values (e.g. "anyref" or "except_ref") to
the runtime system. Therefore lifetime of such a {WasmValue} is directly
coupled to any surrounding {HandleScope}.
For now we just store {Handle<>} directly on the simulated operand stack
of the interpreter. This is of course bogus, since the surrounding scope
does not outlive the interpreter activation. Decoupling the lifetime of
the operand stack from a {HandleScope} will be done in a follow-up CL.
As a drive-by this change also implements support for the "ref_null" and
the "ref_is_null" opcodes as a proof-of-concept that the new {WasmValue}
is also applicable to the "anyref" reference type.
R=clemensh@chromium.org
TEST=cctest/test-run-wasm-interpreter/ReferenceTypeLocals
BUG=v8:8091,v8:7581
Change-Id: I2307e0689a19c4aab1d67f1ba6742cb3cc31aa3c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1550299
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60598}
In the process turn the Torque's Arguments type into a real struct
and add interoperability with it and CSA's CodeStubArguments.
This change is motivated by the desire to include Arguments
in structs (e.g. iterators), which is not possible for constexpr
fields.
Bug: v8:7793
Change-Id: I840538b84c4c58fee75e0b9cd3bdbb3b96a6b948
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1549162
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60597}