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 |