| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index b67441f93797f4ba4f9daea1d052650cfd96a8ab..908115d52ed0367fcb5711746a103fa3f0c5f01c 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -90,6 +90,11 @@ bool LCodeGen::GenerateCode() {
|
| !chunk()->graph()->is_recursive()) ||
|
| !info()->osr_ast_id().IsNone());
|
|
|
| + handler_table_ = isolate()->factory()->NewFixedArray(
|
| + info()->function() != NULL ? info()->function()->handler_count() : 0,
|
| + TENURED);
|
| +
|
| +
|
| return GeneratePrologue() &&
|
| GenerateBody() &&
|
| GenerateDeferredCode() &&
|
| @@ -102,6 +107,7 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
| ASSERT(is_done());
|
| code->set_stack_slots(GetStackSlotCount());
|
| code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
|
| + code->set_handler_table(*handler_table_);
|
| if (FLAG_weak_embedded_maps_in_optimized_code) {
|
| RegisterDependentCodeForEmbeddedMaps(code);
|
| }
|
| @@ -630,7 +636,8 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
|
| : Translation::kSelfLiteralId;
|
| switch (environment->frame_type()) {
|
| case JS_FUNCTION:
|
| - translation->BeginJSFrame(environment->ast_id(), closure_id, height);
|
| + translation->BeginJSFrame(environment->ast_id(), closure_id, height,
|
| + environment->handler_count());
|
| break;
|
| case JS_CONSTRUCT:
|
| translation->BeginConstructStubFrame(closure_id, translation_size);
|
| @@ -1008,6 +1015,16 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
|
| data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
|
| data->SetArgumentsStackHeight(i,
|
| Smi::FromInt(env->arguments_stack_height()));
|
| + // Write the total handler count to the deoptimization data, used to
|
| + // determine the stack sizes.
|
| + int handler_count = 0;
|
| + LEnvironment* current = env;
|
| + do {
|
| + handler_count += current->handler_count();
|
| + current = current->outer();
|
| + } while (current != NULL);
|
| + data->SetHandlerCount(i, Smi::FromInt(handler_count));
|
| +
|
| data->SetPc(i, Smi::FromInt(env->pc_offset()));
|
| }
|
| code->set_deoptimization_data(*data);
|
| @@ -1137,6 +1154,38 @@ void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoEnterTry(LEnterTry* instr) {
|
| + Label try_entry, handler_entry;
|
| + __ jmp(&try_entry);
|
| + __ bind(&handler_entry);
|
| + handler_table_->set(instr->hydrogen()->index(),
|
| + Smi::FromInt(handler_entry.pos()));
|
| + // Save code object.
|
| + __ push(edi);
|
| + // Pass code object as argument.
|
| + __ push(edi);
|
| + // Call Runtime_CatchInOptimizedCode which patches the code with the call to
|
| + // the deopt stub and returns the offset to the address we must jump to.
|
| + __ CallRuntime(Runtime::kCatchInOptimizedCode, 1);
|
| + // Get actual offset.
|
| + __ SmiUntag(eax);
|
| + // Restore code object.
|
| + __ pop(edi);
|
| + // Compute the target PC adding the offset to the code object.
|
| + __ add(edi, eax);
|
| + // Jump to target PC.
|
| + __ jmp(edi);
|
| + __ Abort("Unreachable (the exception should have been caught).");
|
| + __ bind(&try_entry);
|
| + __ PushTryHandler(StackHandler::OPTIMIZED_CATCH, instr->index());
|
| +}
|
| +
|
| +
|
| +void LCodeGen::DoLeaveTry(LLeaveTry* instr) {
|
| + __ PopTryHandler();
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoParameter(LParameter* instr) {
|
| // Nothing to do.
|
| }
|
| @@ -1926,10 +1975,13 @@ void LCodeGen::DoThrow(LThrow* instr) {
|
| ASSERT(ToRegister(instr->context()).is(esi));
|
| CallRuntime(Runtime::kThrow, 1, instr);
|
|
|
| + // Code after a throw now is reachable...
|
| +#if false
|
| if (FLAG_debug_code) {
|
| - Comment("Unreachable code.");
|
| + Comment("Code after a throw should be unreachable.");
|
| __ int3();
|
| }
|
| +#endif
|
| }
|
|
|
|
|
|
|