-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
int Deoptimizer::table_entry_size_ = 16;
+
+int Deoptimizer::patch_size() {
+ const int kCallInstructionSizeInWords = 3;
+ return kCallInstructionSizeInWords * Assembler::kInstrSize;
+}
+
+
+
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
AssertNoAllocation no_allocation;
// For each return after a safepoint insert an absolute call to the
// corresponding deoptimization entry.
+ ASSERT(patch_size() % Assembler::kInstrSize == 0);
+ int call_size_in_words = patch_size() / Assembler::kInstrSize;
unsigned last_pc_offset = 0;
SafepointTable table(function->code());
for (unsigned i = 0; i < table.length(); i++) {
#endif
last_pc_offset = pc_offset;
if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
- const int kCallInstructionSizeInWords = 3;
- CodePatcher patcher(code->instruction_start() + pc_offset + gap_code_size,
- kCallInstructionSizeInWords);
+ last_pc_offset += gap_code_size;
+ CodePatcher patcher(code->instruction_start() + last_pc_offset,
+ call_size_in_words);
Address deoptimization_entry = Deoptimizer::GetDeoptimizationEntry(
deoptimization_index, Deoptimizer::LAZY);
patcher.masm()->Call(deoptimization_entry, RelocInfo::NONE);
- last_pc_offset +=
- gap_code_size + kCallInstructionSizeInWords * Assembler::kInstrSize;
+ last_pc_offset += patch_size();
}
}
LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment(
LInstruction* instr, int ast_id) {
- ASSERT(instructions_pending_deoptimization_environment_ == NULL);
+ ASSERT(instruction_pending_deoptimization_environment_ == NULL);
ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
- instructions_pending_deoptimization_environment_ = instr;
+ instruction_pending_deoptimization_environment_ = instr;
pending_deoptimization_ast_id_ = ast_id;
return instr;
}
void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
- instructions_pending_deoptimization_environment_ = NULL;
+ instruction_pending_deoptimization_environment_ = NULL;
pending_deoptimization_ast_id_ = AstNode::kNoNumber;
}
}
+LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
+ // The control instruction marking the end of a block that completed
+ // abruptly (e.g., threw an exception). There is nothing specific to do.
+ return NULL;
+}
+
+
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
LOperand* value = UseFixed(instr->value(), r0);
return MarkAsCall(new LThrow(value), instr);
if (pending_deoptimization_ast_id_ == instr->ast_id()) {
LInstruction* result = new LLazyBailout;
result = AssignEnvironment(result);
- instructions_pending_deoptimization_environment_->
+ instruction_pending_deoptimization_environment_->
set_deoptimization_environment(result->environment());
ClearInstructionPendingDeoptimizationEnvironment();
return result;
argument_count_(0),
allocator_(allocator),
position_(RelocInfo::kNoPosition),
- instructions_pending_deoptimization_environment_(NULL),
+ instruction_pending_deoptimization_environment_(NULL),
pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
// Build the sequence for the graph.
int argument_count_;
LAllocator* allocator_;
int position_;
- LInstruction* instructions_pending_deoptimization_environment_;
+ LInstruction* instruction_pending_deoptimization_environment_;
int pending_deoptimization_ast_id_;
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
void LCodeGen::CallCode(Handle<Code> code,
RelocInfo::Mode mode,
LInstruction* instr) {
- if (instr != NULL) {
- LPointerMap* pointers = instr->pointer_map();
- RecordPosition(pointers->position());
- __ Call(code, mode);
- RegisterLazyDeoptimization(instr);
- } else {
- LPointerMap no_pointers(0);
- RecordPosition(no_pointers.position());
- __ Call(code, mode);
- RecordSafepoint(&no_pointers, Safepoint::kNoDeoptimizationIndex);
- }
+ ASSERT(instr != NULL);
+ LPointerMap* pointers = instr->pointer_map();
+ RecordPosition(pointers->position());
+ __ Call(code, mode);
+ RegisterLazyDeoptimization(instr);
}
RecordPosition(pointers->position());
__ CallRuntime(function, num_arguments);
- // Runtime calls to Throw are not supposed to ever return at the
- // call site, so don't register lazy deoptimization for these. We do
- // however have to record a safepoint since throwing exceptions can
- // cause garbage collections.
- if (!instr->IsThrow()) {
- RegisterLazyDeoptimization(instr);
- } else {
- RecordSafepoint(instr->pointer_map(), Safepoint::kNoDeoptimizationIndex);
- }
+ RegisterLazyDeoptimization(instr);
}
__ b(ne, &loop);
__ bind(&invoke);
- // Invoke the function. The number of arguments is stored in receiver
- // which is r0, as expected by InvokeFunction.
- v8::internal::ParameterCount actual(receiver);
+ ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+ LPointerMap* pointers = instr->pointer_map();
+ LEnvironment* env = instr->deoptimization_environment();
+ RecordPosition(pointers->position());
+ RegisterEnvironmentForDeoptimization(env);
SafepointGenerator safepoint_generator(this,
- instr->pointer_map(),
- Safepoint::kNoDeoptimizationIndex);
+ pointers,
+ env->deoptimization_index());
+ // The number of arguments is stored in receiver which is r0, as expected
+ // by InvokeFunction.
+ v8::internal::ParameterCount actual(receiver);
__ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
}
Register object = ToRegister(instr->object());
Register key = ToRegister(instr->key());
__ Push(object, key);
- RecordPosition(instr->pointer_map()->position());
+ ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+ LPointerMap* pointers = instr->pointer_map();
+ LEnvironment* env = instr->deoptimization_environment();
+ RecordPosition(pointers->position());
+ RegisterEnvironmentForDeoptimization(env);
SafepointGenerator safepoint_generator(this,
- instr->pointer_map(),
- Safepoint::kNoDeoptimizationIndex);
+ pointers,
+ env->deoptimization_index());
__ InvokeBuiltin(Builtins::DELETE, CALL_JS, &safepoint_generator);
}
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor* visitor);
+ // The size in bytes of the code required at a lazy deopt patch site.
+ static int patch_size();
+
// Patch all stack guard checks in the unoptimized code to
// unconditionally call replacement_code.
static void PatchStackCheckCode(Code* unoptimized_code,
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
+ V(AbnormalExit) \
V(AccessArgumentsAt) \
V(Add) \
V(ApplyArguments) \
};
-class HThrow: public HUnaryControlInstruction {
+class HAbnormalExit: public HControlInstruction {
public:
- explicit HThrow(HValue* value)
- : HUnaryControlInstruction(value, NULL, NULL) { }
+ HAbnormalExit() : HControlInstruction(NULL, NULL) { }
- DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
+ DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
};
};
+class HThrow: public HUnaryOperation {
+ public:
+ explicit HThrow(HValue* value) : HUnaryOperation(value) {
+ SetAllSideEffects();
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
+};
+
+
class HChange: public HUnaryOperation {
public:
HChange(HValue* value,
public:
HStackCheck() { }
- DECLARE_CONCRETE_INSTRUCTION(Throw, "stack_check")
+ DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
};
SetOperandAt(1, receiver);
SetOperandAt(2, length);
SetOperandAt(3, elements);
+ SetAllSideEffects();
}
virtual Representation RequiredInputRepresentation(int index) const {
DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
-
-
protected:
virtual void InternalSetOperandAt(int index, HValue* value) {
operands_[index] = value;
VISIT_FOR_VALUE(expr->exception());
HValue* value = environment()->Pop();
- HControlInstruction* instr = new HThrow(value);
+ HThrow* instr = new HThrow(value);
instr->set_position(expr->position());
- current_subgraph_->FinishExit(instr);
+ AddInstruction(instr);
+ AddSimulate(expr->id());
+ current_subgraph_->FinishExit(new HAbnormalExit);
}
namespace v8 {
namespace internal {
-
int Deoptimizer::table_entry_size_ = 10;
+
+int Deoptimizer::patch_size() {
+ return Assembler::kCallInstructionLength;
+}
+
+
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
AssertNoAllocation no_allocation;
#endif
last_pc_offset = pc_offset;
if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
- Address call_pc = code->instruction_start() + pc_offset + gap_code_size;
- CodePatcher patcher(call_pc, Assembler::kCallInstructionLength);
+ last_pc_offset += gap_code_size;
+ Address call_pc = code->instruction_start() + last_pc_offset;
+ CodePatcher patcher(call_pc, patch_size());
Address entry = GetDeoptimizationEntry(deoptimization_index, LAZY);
patcher.masm()->call(entry, RelocInfo::NONE);
- last_pc_offset += gap_code_size + Assembler::kCallInstructionLength;
+ last_pc_offset += patch_size();
RelocInfo rinfo(call_pc + 1, RelocInfo::RUNTIME_ENTRY,
reinterpret_cast<intptr_t>(entry));
reloc_info_writer.Write(&rinfo);
namespace internal {
+// When invoking builtins, we need to record the safepoint in the middle of
+// the invoke instruction sequence generated by the macro assembler.
class SafepointGenerator : public PostCallGenerator {
public:
SafepointGenerator(LCodeGen* codegen,
void LCodeGen::CallCode(Handle<Code> code,
RelocInfo::Mode mode,
LInstruction* instr) {
- if (instr != NULL) {
- LPointerMap* pointers = instr->pointer_map();
- RecordPosition(pointers->position());
- __ call(code, mode);
- RegisterLazyDeoptimization(instr);
- } else {
- LPointerMap no_pointers(0);
- RecordPosition(no_pointers.position());
- __ call(code, mode);
- RecordSafepoint(&no_pointers, Safepoint::kNoDeoptimizationIndex);
- }
+ ASSERT(instr != NULL);
+ LPointerMap* pointers = instr->pointer_map();
+ RecordPosition(pointers->position());
+ __ call(code, mode);
+ RegisterLazyDeoptimization(instr);
// Signal that we don't inline smi code before these stubs in the
// optimizing code generator.
int num_arguments,
LInstruction* instr) {
ASSERT(instr != NULL);
+ ASSERT(instr->HasPointerMap());
LPointerMap* pointers = instr->pointer_map();
- ASSERT(pointers != NULL);
RecordPosition(pointers->position());
__ CallRuntime(function, num_arguments);
- // Runtime calls to Throw are not supposed to ever return at the
- // call site, so don't register lazy deoptimization for these. We do
- // however have to record a safepoint since throwing exceptions can
- // cause garbage collections.
- // BUG(3243555): register a lazy deoptimization point at throw. We need
- // it to be able to inline functions containing a throw statement.
- if (!instr->IsThrow()) {
- RegisterLazyDeoptimization(instr);
- } else {
- RecordSafepoint(instr->pointer_map(), Safepoint::kNoDeoptimizationIndex);
- }
+ RegisterLazyDeoptimization(instr);
}
// Invoke the function.
__ bind(&invoke);
+ ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+ LPointerMap* pointers = instr->pointer_map();
+ LEnvironment* env = instr->deoptimization_environment();
+ RecordPosition(pointers->position());
+ RegisterEnvironmentForDeoptimization(env);
+ SafepointGenerator safepoint_generator(this,
+ pointers,
+ env->deoptimization_index());
ASSERT(receiver.is(eax));
v8::internal::ParameterCount actual(eax);
- SafepointGenerator safepoint_generator(this,
- instr->pointer_map(),
- Safepoint::kNoDeoptimizationIndex);
__ InvokeFunction(edi, actual, CALL_FUNCTION, &safepoint_generator);
}
} else {
__ push(ToOperand(key));
}
- RecordPosition(instr->pointer_map()->position());
+ ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+ LPointerMap* pointers = instr->pointer_map();
+ LEnvironment* env = instr->deoptimization_environment();
+ RecordPosition(pointers->position());
+ RegisterEnvironmentForDeoptimization(env);
SafepointGenerator safepoint_generator(this,
- instr->pointer_map(),
- Safepoint::kNoDeoptimizationIndex);
+ pointers,
+ env->deoptimization_index());
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
}
LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment(
LInstruction* instr, int ast_id) {
- ASSERT(instructions_pending_deoptimization_environment_ == NULL);
+ ASSERT(instruction_pending_deoptimization_environment_ == NULL);
ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
- instructions_pending_deoptimization_environment_ = instr;
+ instruction_pending_deoptimization_environment_ = instr;
pending_deoptimization_ast_id_ = ast_id;
return instr;
}
void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
- instructions_pending_deoptimization_environment_ = NULL;
+ instruction_pending_deoptimization_environment_ = NULL;
pending_deoptimization_ast_id_ = AstNode::kNoNumber;
}
}
+LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
+ // The control instruction marking the end of a block that completed
+ // abruptly (e.g., threw an exception). There is nothing specific to do.
+ return NULL;
+}
+
+
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
LOperand* value = UseFixed(instr->value(), eax);
return MarkAsCall(new LThrow(value), instr);
// If there is an instruction pending deoptimization environment create a
// lazy bailout instruction to capture the environment.
- if (pending_deoptimization_ast_id_ == instr->ast_id()) {
+ if (pending_deoptimization_ast_id_ != AstNode::kNoNumber) {
+ ASSERT(pending_deoptimization_ast_id_ == instr->ast_id());
LLazyBailout* lazy_bailout = new LLazyBailout;
LInstruction* result = AssignEnvironment(lazy_bailout);
- instructions_pending_deoptimization_environment_->
+ instruction_pending_deoptimization_environment_->
set_deoptimization_environment(result->environment());
ClearInstructionPendingDeoptimizationEnvironment();
return result;
argument_count_(0),
allocator_(allocator),
position_(RelocInfo::kNoPosition),
- instructions_pending_deoptimization_environment_(NULL),
+ instruction_pending_deoptimization_environment_(NULL),
pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
// Build the sequence for the graph.
int argument_count_;
LAllocator* allocator_;
int position_;
- LInstruction* instructions_pending_deoptimization_environment_;
+ LInstruction* instruction_pending_deoptimization_environment_;
int pending_deoptimization_ast_id_;
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
#include "safepoint-table.h"
+#include "deoptimizer.h"
#include "disasm.h"
#include "macro-assembler.h"
void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) {
+ // For lazy deoptimization we need space to patch a call after every call.
+ // Ensure there is always space for such patching, even if the code ends
+ // in a call.
+ int target_offset = assembler->pc_offset() + Deoptimizer::patch_size();
+ while (assembler->pc_offset() < target_offset) {
+ assembler->nop();
+ }
+
// Make sure the safepoint table is properly aligned. Pad with nops.
assembler->Align(kIntSize);
assembler->RecordComment(";;; Safepoint table.");
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
unsigned GetCodeOffset() const;
// Define a new safepoint for the current position in the body.
- Safepoint DefineSafepoint(
- Assembler* assembler,
- Safepoint::Kind kind,
- int arguments,
- int deoptimization_index = Safepoint::kNoDeoptimizationIndex);
+ Safepoint DefineSafepoint(Assembler* assembler,
+ Safepoint::Kind kind,
+ int arguments,
+ int deoptimization_index);
// Update the last safepoint with the size of the code generated for the gap
// following it.
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
int Deoptimizer::table_entry_size_ = 10;
+
+int Deoptimizer::patch_size() {
+ return Assembler::kCallInstructionLength;
+}
+
+
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
AssertNoAllocation no_allocation;
#endif
last_pc_offset = pc_offset;
if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
- CodePatcher patcher(
- code->instruction_start() + pc_offset + gap_code_size,
- Assembler::kCallInstructionLength);
+ last_pc_offset += gap_code_size;
+ CodePatcher patcher(code->instruction_start() + last_pc_offset,
+ patch_size());
patcher.masm()->Call(GetDeoptimizationEntry(deoptimization_index, LAZY),
RelocInfo::NONE);
- last_pc_offset += gap_code_size + Assembler::kCallInstructionLength;
+ last_pc_offset += patch_size();
}
}
#ifdef DEBUG
void LCodeGen::CallCode(Handle<Code> code,
RelocInfo::Mode mode,
LInstruction* instr) {
- if (instr != NULL) {
- LPointerMap* pointers = instr->pointer_map();
- RecordPosition(pointers->position());
- __ call(code, mode);
- RegisterLazyDeoptimization(instr);
- } else {
- LPointerMap no_pointers(0);
- RecordPosition(no_pointers.position());
- __ call(code, mode);
- RecordSafepoint(&no_pointers, Safepoint::kNoDeoptimizationIndex);
- }
+ ASSERT(instr != NULL);
+ LPointerMap* pointers = instr->pointer_map();
+ RecordPosition(pointers->position());
+ __ call(code, mode);
+ RegisterLazyDeoptimization(instr);
// Signal that we don't inline smi code before these stubs in the
// optimizing code generator.
LInstruction* instr, int ast_id) {
ASSERT(instructions_pending_deoptimization_environment_ == NULL);
ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
- instructions_pending_deoptimization_environment_ = instr;
+ instruction_pending_deoptimization_environment_ = instr;
pending_deoptimization_ast_id_ = ast_id;
return instr;
}
void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
- instructions_pending_deoptimization_environment_ = NULL;
+ instruction_pending_deoptimization_environment_ = NULL;
pending_deoptimization_ast_id_ = AstNode::kNoNumber;
}
}
+LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
+ // The control instruction marking the end of a block that completed
+ // abruptly (e.g., threw an exception). There is nothing specific to do.
+ return NULL;
+}
+
+
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
Abort("Unimplemented: %s", "DoThrow");
return NULL;
if (pending_deoptimization_ast_id_ == instr->ast_id()) {
LLazyBailout* lazy_bailout = new LLazyBailout;
LInstruction* result = AssignEnvironment(lazy_bailout);
- instructions_pending_deoptimization_environment_->
+ instruction_pending_deoptimization_environment_->
set_deoptimization_environment(result->environment());
ClearInstructionPendingDeoptimizationEnvironment();
return result;
argument_count_(0),
allocator_(allocator),
position_(RelocInfo::kNoPosition),
- instructions_pending_deoptimization_environment_(NULL),
+ instruction_pending_deoptimization_environment_(NULL),
pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
// Build the sequence for the graph.
int argument_count_;
LAllocator* allocator_;
int position_;
- LInstruction* instructions_pending_deoptimization_environment_;
+ LInstruction* instruction_pending_deoptimization_environment_;
int pending_deoptimization_ast_id_;
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
test-serialize/TestThatAlwaysFails: FAIL
test-serialize/DependentTestThatAlwaysFails: FAIL
-# BUG(1079)
-test-api/CaptureStackTraceForUncaughtException: PASS || FAIL
-
##############################################################################
[ $arch == x64 ]
--- /dev/null
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Getting the arguments property of an optimized function should not crash,
+// even if called through our optimized version of Function.prototype.apply.
+
+function optimized() {
+ return unoptimized.apply(null, arguments);
+}
+
+// It's not crucial that this is unoptimized.
+function unoptimized() {
+ with ({}) {
+ return optimized.arguments;
+ }
+}
+
+for (var i = 0; i < 100000; ++i) {
+ optimized(1, 2, 3)
+}
+