| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 | 348 |
| 349 int LCodeGen::ToInteger32(LConstantOperand* op) const { | 349 int LCodeGen::ToInteger32(LConstantOperand* op) const { |
| 350 Handle<Object> value = chunk_->LookupLiteral(op); | 350 Handle<Object> value = chunk_->LookupLiteral(op); |
| 351 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); | 351 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); |
| 352 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == | 352 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == |
| 353 value->Number()); | 353 value->Number()); |
| 354 return static_cast<int32_t>(value->Number()); | 354 return static_cast<int32_t>(value->Number()); |
| 355 } | 355 } |
| 356 | 356 |
| 357 | 357 |
| 358 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
| 359 Handle<Object> literal = chunk_->LookupLiteral(op); |
| 360 ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged()); |
| 361 return literal; |
| 362 } |
| 363 |
| 364 |
| 358 Immediate LCodeGen::ToImmediate(LOperand* op) { | 365 Immediate LCodeGen::ToImmediate(LOperand* op) { |
| 359 LConstantOperand* const_op = LConstantOperand::cast(op); | 366 LConstantOperand* const_op = LConstantOperand::cast(op); |
| 360 Handle<Object> literal = chunk_->LookupLiteral(const_op); | 367 Handle<Object> literal = chunk_->LookupLiteral(const_op); |
| 361 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 368 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 362 if (r.IsInteger32()) { | 369 if (r.IsInteger32()) { |
| 363 ASSERT(literal->IsNumber()); | 370 ASSERT(literal->IsNumber()); |
| 364 return Immediate(static_cast<int32_t>(literal->Number())); | 371 return Immediate(static_cast<int32_t>(literal->Number())); |
| 365 } else if (r.IsDouble()) { | 372 } else if (r.IsDouble()) { |
| 366 Abort("unsupported double immediate"); | 373 Abort("unsupported double immediate"); |
| 367 } | 374 } |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 LOperand* context) { | 528 LOperand* context) { |
| 522 if (context->IsRegister()) { | 529 if (context->IsRegister()) { |
| 523 if (!ToRegister(context).is(esi)) { | 530 if (!ToRegister(context).is(esi)) { |
| 524 __ mov(esi, ToRegister(context)); | 531 __ mov(esi, ToRegister(context)); |
| 525 } | 532 } |
| 526 } else if (context->IsStackSlot()) { | 533 } else if (context->IsStackSlot()) { |
| 527 __ mov(esi, ToOperand(context)); | 534 __ mov(esi, ToOperand(context)); |
| 528 } else if (context->IsConstantOperand()) { | 535 } else if (context->IsConstantOperand()) { |
| 529 Handle<Object> literal = | 536 Handle<Object> literal = |
| 530 chunk_->LookupLiteral(LConstantOperand::cast(context)); | 537 chunk_->LookupLiteral(LConstantOperand::cast(context)); |
| 531 LoadHeapObject(esi, Handle<Context>::cast(literal)); | 538 __ LoadHeapObject(esi, Handle<Context>::cast(literal)); |
| 532 } else { | 539 } else { |
| 533 UNREACHABLE(); | 540 UNREACHABLE(); |
| 534 } | 541 } |
| 535 | 542 |
| 536 __ CallRuntimeSaveDoubles(id); | 543 __ CallRuntimeSaveDoubles(id); |
| 537 RecordSafepointWithRegisters( | 544 RecordSafepointWithRegisters( |
| 538 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex); | 545 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex); |
| 539 } | 546 } |
| 540 | 547 |
| 541 | 548 |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 } | 1245 } |
| 1239 } | 1246 } |
| 1240 } | 1247 } |
| 1241 } | 1248 } |
| 1242 | 1249 |
| 1243 | 1250 |
| 1244 void LCodeGen::DoConstantT(LConstantT* instr) { | 1251 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1245 Register reg = ToRegister(instr->result()); | 1252 Register reg = ToRegister(instr->result()); |
| 1246 Handle<Object> handle = instr->value(); | 1253 Handle<Object> handle = instr->value(); |
| 1247 if (handle->IsHeapObject()) { | 1254 if (handle->IsHeapObject()) { |
| 1248 LoadHeapObject(reg, Handle<HeapObject>::cast(handle)); | 1255 __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle)); |
| 1249 } else { | 1256 } else { |
| 1250 __ Set(reg, Immediate(handle)); | 1257 __ Set(reg, Immediate(handle)); |
| 1251 } | 1258 } |
| 1252 } | 1259 } |
| 1253 | 1260 |
| 1254 | 1261 |
| 1255 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { | 1262 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { |
| 1256 Register result = ToRegister(instr->result()); | 1263 Register result = ToRegister(instr->result()); |
| 1257 Register array = ToRegister(instr->InputAt(0)); | 1264 Register array = ToRegister(instr->InputAt(0)); |
| 1258 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); | 1265 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1981 flags = static_cast<InstanceofStub::Flags>( | 1988 flags = static_cast<InstanceofStub::Flags>( |
| 1982 flags | InstanceofStub::kReturnTrueFalseObject); | 1989 flags | InstanceofStub::kReturnTrueFalseObject); |
| 1983 InstanceofStub stub(flags); | 1990 InstanceofStub stub(flags); |
| 1984 | 1991 |
| 1985 // Get the temp register reserved by the instruction. This needs to be a | 1992 // Get the temp register reserved by the instruction. This needs to be a |
| 1986 // register which is pushed last by PushSafepointRegisters as top of the | 1993 // register which is pushed last by PushSafepointRegisters as top of the |
| 1987 // stack is used to pass the offset to the location of the map check to | 1994 // stack is used to pass the offset to the location of the map check to |
| 1988 // the stub. | 1995 // the stub. |
| 1989 Register temp = ToRegister(instr->TempAt(0)); | 1996 Register temp = ToRegister(instr->TempAt(0)); |
| 1990 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); | 1997 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); |
| 1991 __ mov(InstanceofStub::right(), Immediate(instr->function())); | 1998 __ LoadHeapObject(InstanceofStub::right(), instr->function()); |
| 1992 static const int kAdditionalDelta = 13; | 1999 static const int kAdditionalDelta = 13; |
| 1993 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; | 2000 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; |
| 1994 __ mov(temp, Immediate(delta)); | 2001 __ mov(temp, Immediate(delta)); |
| 1995 __ StoreToSafepointRegisterSlot(temp, temp); | 2002 __ StoreToSafepointRegisterSlot(temp, temp); |
| 1996 CallCodeGeneric(stub.GetCode(), | 2003 CallCodeGeneric(stub.GetCode(), |
| 1997 RelocInfo::CODE_TARGET, | 2004 RelocInfo::CODE_TARGET, |
| 1998 instr, | 2005 instr, |
| 1999 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 2006 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
| 2000 // Put the result value into the eax slot and restore all registers. | 2007 // Put the result value into the eax slot and restore all registers. |
| 2001 __ StoreToSafepointRegisterSlot(eax, eax); | 2008 __ StoreToSafepointRegisterSlot(eax, eax); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2184 // Negative property indices are in-object properties, indexed | 2191 // Negative property indices are in-object properties, indexed |
| 2185 // from the end of the fixed part of the object. | 2192 // from the end of the fixed part of the object. |
| 2186 __ mov(result, FieldOperand(object, offset + type->instance_size())); | 2193 __ mov(result, FieldOperand(object, offset + type->instance_size())); |
| 2187 } else { | 2194 } else { |
| 2188 // Non-negative property indices are in the properties array. | 2195 // Non-negative property indices are in the properties array. |
| 2189 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 2196 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 2190 __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); | 2197 __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); |
| 2191 } | 2198 } |
| 2192 } else { | 2199 } else { |
| 2193 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); | 2200 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); |
| 2194 LoadHeapObject(result, Handle<HeapObject>::cast(function)); | 2201 __ LoadHeapObject(result, function); |
| 2202 } |
| 2203 } |
| 2204 |
| 2205 |
| 2206 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { |
| 2207 ASSERT(!operand->IsDoubleRegister()); |
| 2208 if (operand->IsConstantOperand()) { |
| 2209 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); |
| 2210 if (object->IsSmi()) { |
| 2211 __ Push(Handle<Smi>::cast(object)); |
| 2212 } else { |
| 2213 __ PushHeapObject(Handle<HeapObject>::cast(object)); |
| 2214 } |
| 2215 } else if (operand->IsRegister()) { |
| 2216 __ push(ToRegister(operand)); |
| 2217 } else { |
| 2218 __ push(ToOperand(operand)); |
| 2195 } | 2219 } |
| 2196 } | 2220 } |
| 2197 | 2221 |
| 2198 | 2222 |
| 2199 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { | 2223 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { |
| 2200 Register object = ToRegister(instr->object()); | 2224 Register object = ToRegister(instr->object()); |
| 2201 Register result = ToRegister(instr->result()); | 2225 Register result = ToRegister(instr->result()); |
| 2202 | 2226 |
| 2203 int map_count = instr->hydrogen()->types()->length(); | 2227 int map_count = instr->hydrogen()->types()->length(); |
| 2204 Handle<String> name = instr->hydrogen()->name(); | 2228 Handle<String> name = instr->hydrogen()->name(); |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2597 pointers, | 2621 pointers, |
| 2598 env->deoptimization_index()); | 2622 env->deoptimization_index()); |
| 2599 ParameterCount actual(eax); | 2623 ParameterCount actual(eax); |
| 2600 __ InvokeFunction(function, actual, CALL_FUNCTION, | 2624 __ InvokeFunction(function, actual, CALL_FUNCTION, |
| 2601 safepoint_generator, CALL_AS_METHOD); | 2625 safepoint_generator, CALL_AS_METHOD); |
| 2602 } | 2626 } |
| 2603 | 2627 |
| 2604 | 2628 |
| 2605 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 2629 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
| 2606 LOperand* argument = instr->InputAt(0); | 2630 LOperand* argument = instr->InputAt(0); |
| 2607 if (argument->IsConstantOperand()) { | 2631 EmitPushTaggedOperand(argument); |
| 2608 __ push(ToImmediate(argument)); | |
| 2609 } else { | |
| 2610 __ push(ToOperand(argument)); | |
| 2611 } | |
| 2612 } | 2632 } |
| 2613 | 2633 |
| 2614 | 2634 |
| 2615 void LCodeGen::DoThisFunction(LThisFunction* instr) { | 2635 void LCodeGen::DoThisFunction(LThisFunction* instr) { |
| 2616 Register result = ToRegister(instr->result()); | 2636 Register result = ToRegister(instr->result()); |
| 2617 __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 2637 __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2618 } | 2638 } |
| 2619 | 2639 |
| 2620 | 2640 |
| 2621 void LCodeGen::DoContext(LContext* instr) { | 2641 void LCodeGen::DoContext(LContext* instr) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2678 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 2698 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
| 2679 } | 2699 } |
| 2680 | 2700 |
| 2681 // Setup deoptimization. | 2701 // Setup deoptimization. |
| 2682 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); | 2702 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); |
| 2683 } | 2703 } |
| 2684 | 2704 |
| 2685 | 2705 |
| 2686 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2706 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 2687 ASSERT(ToRegister(instr->result()).is(eax)); | 2707 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2688 __ mov(edi, instr->function()); | 2708 __ LoadHeapObject(edi, instr->function()); |
| 2689 CallKnownFunction(instr->function(), | 2709 CallKnownFunction(instr->function(), |
| 2690 instr->arity(), | 2710 instr->arity(), |
| 2691 instr, | 2711 instr, |
| 2692 CALL_AS_METHOD); | 2712 CALL_AS_METHOD); |
| 2693 } | 2713 } |
| 2694 | 2714 |
| 2695 | 2715 |
| 2696 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2716 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
| 2697 Register input_reg = ToRegister(instr->value()); | 2717 Register input_reg = ToRegister(instr->value()); |
| 2698 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 2718 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3108 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; | 3128 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; |
| 3109 Handle<Code> ic = | 3129 Handle<Code> ic = |
| 3110 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3130 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
| 3111 __ mov(ecx, instr->name()); | 3131 __ mov(ecx, instr->name()); |
| 3112 CallCode(ic, mode, instr); | 3132 CallCode(ic, mode, instr); |
| 3113 } | 3133 } |
| 3114 | 3134 |
| 3115 | 3135 |
| 3116 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3136 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
| 3117 ASSERT(ToRegister(instr->result()).is(eax)); | 3137 ASSERT(ToRegister(instr->result()).is(eax)); |
| 3118 __ mov(edi, instr->target()); | 3138 __ LoadHeapObject(edi, instr->target()); |
| 3119 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); | 3139 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
| 3120 } | 3140 } |
| 3121 | 3141 |
| 3122 | 3142 |
| 3123 void LCodeGen::DoCallNew(LCallNew* instr) { | 3143 void LCodeGen::DoCallNew(LCallNew* instr) { |
| 3124 ASSERT(ToRegister(instr->context()).is(esi)); | 3144 ASSERT(ToRegister(instr->context()).is(esi)); |
| 3125 ASSERT(ToRegister(instr->constructor()).is(edi)); | 3145 ASSERT(ToRegister(instr->constructor()).is(edi)); |
| 3126 ASSERT(ToRegister(instr->result()).is(eax)); | 3146 ASSERT(ToRegister(instr->result()).is(eax)); |
| 3127 | 3147 |
| 3128 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3148 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3475 | 3495 |
| 3476 | 3496 |
| 3477 void LCodeGen::DoStringLength(LStringLength* instr) { | 3497 void LCodeGen::DoStringLength(LStringLength* instr) { |
| 3478 Register string = ToRegister(instr->string()); | 3498 Register string = ToRegister(instr->string()); |
| 3479 Register result = ToRegister(instr->result()); | 3499 Register result = ToRegister(instr->result()); |
| 3480 __ mov(result, FieldOperand(string, String::kLengthOffset)); | 3500 __ mov(result, FieldOperand(string, String::kLengthOffset)); |
| 3481 } | 3501 } |
| 3482 | 3502 |
| 3483 | 3503 |
| 3484 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 3504 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
| 3485 if (instr->left()->IsConstantOperand()) { | 3505 EmitPushTaggedOperand(instr->left()); |
| 3486 __ push(ToImmediate(instr->left())); | 3506 EmitPushTaggedOperand(instr->right()); |
| 3487 } else { | |
| 3488 __ push(ToOperand(instr->left())); | |
| 3489 } | |
| 3490 if (instr->right()->IsConstantOperand()) { | |
| 3491 __ push(ToImmediate(instr->right())); | |
| 3492 } else { | |
| 3493 __ push(ToOperand(instr->right())); | |
| 3494 } | |
| 3495 StringAddStub stub(NO_STRING_CHECK_IN_STUB); | 3507 StringAddStub stub(NO_STRING_CHECK_IN_STUB); |
| 3496 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 3508 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 3497 } | 3509 } |
| 3498 | 3510 |
| 3499 | 3511 |
| 3500 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 3512 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 3501 LOperand* input = instr->InputAt(0); | 3513 LOperand* input = instr->InputAt(0); |
| 3502 ASSERT(input->IsRegister() || input->IsStackSlot()); | 3514 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 3503 LOperand* output = instr->result(); | 3515 LOperand* output = instr->result(); |
| 3504 ASSERT(output->IsDoubleRegister()); | 3516 ASSERT(output->IsDoubleRegister()); |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3984 | 3996 |
| 3985 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 3997 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
| 3986 Handle<JSFunction> target = instr->hydrogen()->target(); | 3998 Handle<JSFunction> target = instr->hydrogen()->target(); |
| 3987 if (isolate()->heap()->InNewSpace(*target)) { | 3999 if (isolate()->heap()->InNewSpace(*target)) { |
| 3988 Register reg = ToRegister(instr->value()); | 4000 Register reg = ToRegister(instr->value()); |
| 3989 Handle<JSGlobalPropertyCell> cell = | 4001 Handle<JSGlobalPropertyCell> cell = |
| 3990 isolate()->factory()->NewJSGlobalPropertyCell(target); | 4002 isolate()->factory()->NewJSGlobalPropertyCell(target); |
| 3991 __ cmp(reg, Operand::Cell(cell)); | 4003 __ cmp(reg, Operand::Cell(cell)); |
| 3992 } else { | 4004 } else { |
| 3993 Operand operand = ToOperand(instr->value()); | 4005 Operand operand = ToOperand(instr->value()); |
| 3994 __ cmp(operand, instr->hydrogen()->target()); | 4006 __ cmp(operand, target); |
| 3995 } | 4007 } |
| 3996 DeoptimizeIf(not_equal, instr->environment()); | 4008 DeoptimizeIf(not_equal, instr->environment()); |
| 3997 } | 4009 } |
| 3998 | 4010 |
| 3999 | 4011 |
| 4000 void LCodeGen::DoCheckMap(LCheckMap* instr) { | 4012 void LCodeGen::DoCheckMap(LCheckMap* instr) { |
| 4001 LOperand* input = instr->InputAt(0); | 4013 LOperand* input = instr->InputAt(0); |
| 4002 ASSERT(input->IsRegister()); | 4014 ASSERT(input->IsRegister()); |
| 4003 Register reg = ToRegister(input); | 4015 Register reg = ToRegister(input); |
| 4004 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 4016 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4048 | 4060 |
| 4049 // smi | 4061 // smi |
| 4050 __ bind(&is_smi); | 4062 __ bind(&is_smi); |
| 4051 __ SmiUntag(input_reg); | 4063 __ SmiUntag(input_reg); |
| 4052 __ ClampUint8(input_reg); | 4064 __ ClampUint8(input_reg); |
| 4053 | 4065 |
| 4054 __ bind(&done); | 4066 __ bind(&done); |
| 4055 } | 4067 } |
| 4056 | 4068 |
| 4057 | 4069 |
| 4058 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { | |
| 4059 if (isolate()->heap()->InNewSpace(*object)) { | |
| 4060 Handle<JSGlobalPropertyCell> cell = | |
| 4061 isolate()->factory()->NewJSGlobalPropertyCell(object); | |
| 4062 __ mov(result, Operand::Cell(cell)); | |
| 4063 } else { | |
| 4064 __ mov(result, object); | |
| 4065 } | |
| 4066 } | |
| 4067 | |
| 4068 | |
| 4069 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { | 4070 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { |
| 4070 Register reg = ToRegister(instr->TempAt(0)); | 4071 Register reg = ToRegister(instr->TempAt(0)); |
| 4071 | 4072 |
| 4072 Handle<JSObject> holder = instr->holder(); | 4073 Handle<JSObject> holder = instr->holder(); |
| 4073 Handle<JSObject> current_prototype = instr->prototype(); | 4074 Handle<JSObject> current_prototype = instr->prototype(); |
| 4074 | 4075 |
| 4075 // Load prototype object. | 4076 // Load prototype object. |
| 4076 LoadHeapObject(reg, current_prototype); | 4077 __ LoadHeapObject(reg, current_prototype); |
| 4077 | 4078 |
| 4078 // Check prototype maps up to the holder. | 4079 // Check prototype maps up to the holder. |
| 4079 while (!current_prototype.is_identical_to(holder)) { | 4080 while (!current_prototype.is_identical_to(holder)) { |
| 4080 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 4081 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 4081 Handle<Map>(current_prototype->map())); | 4082 Handle<Map>(current_prototype->map())); |
| 4082 DeoptimizeIf(not_equal, instr->environment()); | 4083 DeoptimizeIf(not_equal, instr->environment()); |
| 4083 current_prototype = | 4084 current_prototype = |
| 4084 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); | 4085 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); |
| 4085 // Load next prototype object. | 4086 // Load next prototype object. |
| 4086 LoadHeapObject(reg, current_prototype); | 4087 __ LoadHeapObject(reg, current_prototype); |
| 4087 } | 4088 } |
| 4088 | 4089 |
| 4089 // Check the holder map. | 4090 // Check the holder map. |
| 4090 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 4091 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 4091 Handle<Map>(current_prototype->map())); | 4092 Handle<Map>(current_prototype->map())); |
| 4092 DeoptimizeIf(not_equal, instr->environment()); | 4093 DeoptimizeIf(not_equal, instr->environment()); |
| 4093 } | 4094 } |
| 4094 | 4095 |
| 4095 | 4096 |
| 4096 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 4097 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4224 __ push(Immediate(pretenure | 4225 __ push(Immediate(pretenure |
| 4225 ? factory()->true_value() | 4226 ? factory()->true_value() |
| 4226 : factory()->false_value())); | 4227 : factory()->false_value())); |
| 4227 CallRuntime(Runtime::kNewClosure, 3, instr); | 4228 CallRuntime(Runtime::kNewClosure, 3, instr); |
| 4228 } | 4229 } |
| 4229 } | 4230 } |
| 4230 | 4231 |
| 4231 | 4232 |
| 4232 void LCodeGen::DoTypeof(LTypeof* instr) { | 4233 void LCodeGen::DoTypeof(LTypeof* instr) { |
| 4233 LOperand* input = instr->InputAt(1); | 4234 LOperand* input = instr->InputAt(1); |
| 4234 if (input->IsConstantOperand()) { | 4235 EmitPushTaggedOperand(input); |
| 4235 __ push(ToImmediate(input)); | |
| 4236 } else { | |
| 4237 __ push(ToOperand(input)); | |
| 4238 } | |
| 4239 CallRuntime(Runtime::kTypeof, 1, instr); | 4236 CallRuntime(Runtime::kTypeof, 1, instr); |
| 4240 } | 4237 } |
| 4241 | 4238 |
| 4242 | 4239 |
| 4243 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 4240 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 4244 Register input = ToRegister(instr->InputAt(0)); | 4241 Register input = ToRegister(instr->InputAt(0)); |
| 4245 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4242 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 4246 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4243 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 4247 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 4244 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 4248 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 4245 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4364 | 4361 |
| 4365 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { | 4362 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { |
| 4366 DeoptimizeIf(no_condition, instr->environment()); | 4363 DeoptimizeIf(no_condition, instr->environment()); |
| 4367 } | 4364 } |
| 4368 | 4365 |
| 4369 | 4366 |
| 4370 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { | 4367 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { |
| 4371 LOperand* obj = instr->object(); | 4368 LOperand* obj = instr->object(); |
| 4372 LOperand* key = instr->key(); | 4369 LOperand* key = instr->key(); |
| 4373 __ push(ToOperand(obj)); | 4370 __ push(ToOperand(obj)); |
| 4374 if (key->IsConstantOperand()) { | 4371 EmitPushTaggedOperand(key); |
| 4375 __ push(ToImmediate(key)); | |
| 4376 } else { | |
| 4377 __ push(ToOperand(key)); | |
| 4378 } | |
| 4379 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); | 4372 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); |
| 4380 LPointerMap* pointers = instr->pointer_map(); | 4373 LPointerMap* pointers = instr->pointer_map(); |
| 4381 LEnvironment* env = instr->deoptimization_environment(); | 4374 LEnvironment* env = instr->deoptimization_environment(); |
| 4382 RecordPosition(pointers->position()); | 4375 RecordPosition(pointers->position()); |
| 4383 RegisterEnvironmentForDeoptimization(env); | 4376 RegisterEnvironmentForDeoptimization(env); |
| 4384 // Create safepoint generator that will also ensure enough space in the | 4377 // Create safepoint generator that will also ensure enough space in the |
| 4385 // reloc info for patching in deoptimization (since this is invoking a | 4378 // reloc info for patching in deoptimization (since this is invoking a |
| 4386 // builtin) | 4379 // builtin) |
| 4387 SafepointGenerator safepoint_generator(this, | 4380 SafepointGenerator safepoint_generator(this, |
| 4388 pointers, | 4381 pointers, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4459 ASSERT(!environment->HasBeenRegistered()); | 4452 ASSERT(!environment->HasBeenRegistered()); |
| 4460 RegisterEnvironmentForDeoptimization(environment); | 4453 RegisterEnvironmentForDeoptimization(environment); |
| 4461 ASSERT(osr_pc_offset_ == -1); | 4454 ASSERT(osr_pc_offset_ == -1); |
| 4462 osr_pc_offset_ = masm()->pc_offset(); | 4455 osr_pc_offset_ = masm()->pc_offset(); |
| 4463 } | 4456 } |
| 4464 | 4457 |
| 4465 | 4458 |
| 4466 void LCodeGen::DoIn(LIn* instr) { | 4459 void LCodeGen::DoIn(LIn* instr) { |
| 4467 LOperand* obj = instr->object(); | 4460 LOperand* obj = instr->object(); |
| 4468 LOperand* key = instr->key(); | 4461 LOperand* key = instr->key(); |
| 4469 if (key->IsConstantOperand()) { | 4462 EmitPushTaggedOperand(key); |
| 4470 __ push(ToImmediate(key)); | 4463 EmitPushTaggedOperand(obj); |
| 4471 } else { | |
| 4472 __ push(ToOperand(key)); | |
| 4473 } | |
| 4474 if (obj->IsConstantOperand()) { | |
| 4475 __ push(ToImmediate(obj)); | |
| 4476 } else { | |
| 4477 __ push(ToOperand(obj)); | |
| 4478 } | |
| 4479 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); | 4464 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); |
| 4480 LPointerMap* pointers = instr->pointer_map(); | 4465 LPointerMap* pointers = instr->pointer_map(); |
| 4481 LEnvironment* env = instr->deoptimization_environment(); | 4466 LEnvironment* env = instr->deoptimization_environment(); |
| 4482 RecordPosition(pointers->position()); | 4467 RecordPosition(pointers->position()); |
| 4483 RegisterEnvironmentForDeoptimization(env); | 4468 RegisterEnvironmentForDeoptimization(env); |
| 4484 // Create safepoint generator that will also ensure enough space in the | 4469 // Create safepoint generator that will also ensure enough space in the |
| 4485 // reloc info for patching in deoptimization (since this is invoking a | 4470 // reloc info for patching in deoptimization (since this is invoking a |
| 4486 // builtin) | 4471 // builtin) |
| 4487 SafepointGenerator safepoint_generator(this, | 4472 SafepointGenerator safepoint_generator(this, |
| 4488 pointers, | 4473 pointers, |
| 4489 env->deoptimization_index()); | 4474 env->deoptimization_index()); |
| 4490 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4475 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
| 4491 } | 4476 } |
| 4492 | 4477 |
| 4493 | 4478 |
| 4494 #undef __ | 4479 #undef __ |
| 4495 | 4480 |
| 4496 } } // namespace v8::internal | 4481 } } // namespace v8::internal |
| 4497 | 4482 |
| 4498 #endif // V8_TARGET_ARCH_IA32 | 4483 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |