| Index: src/ia32/lithium-codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/lithium-codegen-ia32.cc (revision 7030)
|
| +++ src/ia32/lithium-codegen-ia32.cc (working copy)
|
| @@ -37,6 +37,8 @@
|
| 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,
|
| @@ -366,17 +368,11 @@
|
| 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.
|
| @@ -391,22 +387,12 @@
|
| 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);
|
| }
|
|
|
|
|
| @@ -566,37 +552,40 @@
|
| }
|
|
|
|
|
| -void LCodeGen::RecordSafepoint(LPointerMap* pointers,
|
| - int deoptimization_index) {
|
| +void LCodeGen::RecordSafepoint(
|
| + LPointerMap* pointers,
|
| + Safepoint::Kind kind,
|
| + int arguments,
|
| + int deoptimization_index) {
|
| const ZoneList<LOperand*>* operands = pointers->operands();
|
| Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
|
| - deoptimization_index);
|
| + kind, arguments, deoptimization_index);
|
| for (int i = 0; i < operands->length(); i++) {
|
| LOperand* pointer = operands->at(i);
|
| if (pointer->IsStackSlot()) {
|
| safepoint.DefinePointerSlot(pointer->index());
|
| + } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
|
| + safepoint.DefinePointerRegister(ToRegister(pointer));
|
| }
|
| }
|
| + if (kind & Safepoint::kWithRegisters) {
|
| + // Register esi always contains a pointer to the context.
|
| + safepoint.DefinePointerRegister(esi);
|
| + }
|
| }
|
|
|
|
|
| +void LCodeGen::RecordSafepoint(LPointerMap* pointers,
|
| + int deoptimization_index) {
|
| + RecordSafepoint(pointers, Safepoint::kSimple, 0, deoptimization_index);
|
| +}
|
| +
|
| +
|
| void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
|
| int arguments,
|
| int deoptimization_index) {
|
| - const ZoneList<LOperand*>* operands = pointers->operands();
|
| - Safepoint safepoint =
|
| - safepoints_.DefineSafepointWithRegisters(
|
| - masm(), arguments, deoptimization_index);
|
| - for (int i = 0; i < operands->length(); i++) {
|
| - LOperand* pointer = operands->at(i);
|
| - if (pointer->IsStackSlot()) {
|
| - safepoint.DefinePointerSlot(pointer->index());
|
| - } else if (pointer->IsRegister()) {
|
| - safepoint.DefinePointerRegister(ToRegister(pointer));
|
| - }
|
| - }
|
| - // Register esi always contains a pointer to the context.
|
| - safepoint.DefinePointerRegister(esi);
|
| + RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments,
|
| + deoptimization_index);
|
| }
|
|
|
|
|
| @@ -1908,7 +1897,19 @@
|
|
|
| void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
|
| Register value = ToRegister(instr->InputAt(0));
|
| - __ mov(Operand::Cell(instr->hydrogen()->cell()), value);
|
| + Operand cell_operand = Operand::Cell(instr->hydrogen()->cell());
|
| +
|
| + // If the cell we are storing to contains the hole it could have
|
| + // been deleted from the property dictionary. In that case, we need
|
| + // to update the property details in the property dictionary to mark
|
| + // it as no longer deleted. We deoptimize in that case.
|
| + if (instr->hydrogen()->check_hole_value()) {
|
| + __ cmp(cell_operand, FACTORY->the_hole_value());
|
| + DeoptimizeIf(equal, instr->environment());
|
| + }
|
| +
|
| + // Store the value.
|
| + __ mov(cell_operand, value);
|
| }
|
|
|
|
|
| @@ -2132,11 +2133,16 @@
|
|
|
| // 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);
|
| }
|
|
|
| @@ -2384,6 +2390,8 @@
|
| __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity));
|
| __ ucomisd(xmm_scratch, input_reg);
|
| DeoptimizeIf(equal, instr->environment());
|
| + __ xorpd(xmm_scratch, xmm_scratch);
|
| + __ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
|
| __ sqrtsd(input_reg, input_reg);
|
| }
|
|
|
| @@ -3568,10 +3576,14 @@
|
| } 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);
|
| }
|
|
|
|
|