Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 8111006: Allow new-space JSFunction objects as constant-function properties. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: rebased Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 334
335 int LCodeGen::ToInteger32(LConstantOperand* op) const { 335 int LCodeGen::ToInteger32(LConstantOperand* op) const {
336 Handle<Object> value = chunk_->LookupLiteral(op); 336 Handle<Object> value = chunk_->LookupLiteral(op);
337 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); 337 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
338 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == 338 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) ==
339 value->Number()); 339 value->Number());
340 return static_cast<int32_t>(value->Number()); 340 return static_cast<int32_t>(value->Number());
341 } 341 }
342 342
343 343
344 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
345 Handle<Object> literal = chunk_->LookupLiteral(op);
346 ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
347 return literal;
348 }
349
350
344 double LCodeGen::ToDouble(LConstantOperand* op) const { 351 double LCodeGen::ToDouble(LConstantOperand* op) const {
345 Handle<Object> value = chunk_->LookupLiteral(op); 352 Handle<Object> value = chunk_->LookupLiteral(op);
346 return value->Number(); 353 return value->Number();
347 } 354 }
348 355
349 356
350 Immediate LCodeGen::ToImmediate(LOperand* op) { 357 Immediate LCodeGen::ToImmediate(LOperand* op) {
351 LConstantOperand* const_op = LConstantOperand::cast(op); 358 LConstantOperand* const_op = LConstantOperand::cast(op);
352 Handle<Object> literal = chunk_->LookupLiteral(const_op); 359 Handle<Object> literal = chunk_->LookupLiteral(const_op);
353 Representation r = chunk_->LookupLiteralRepresentation(const_op); 360 Representation r = chunk_->LookupLiteralRepresentation(const_op);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 LOperand* context) { 518 LOperand* context) {
512 if (context->IsRegister()) { 519 if (context->IsRegister()) {
513 if (!ToRegister(context).is(esi)) { 520 if (!ToRegister(context).is(esi)) {
514 __ mov(esi, ToRegister(context)); 521 __ mov(esi, ToRegister(context));
515 } 522 }
516 } else if (context->IsStackSlot()) { 523 } else if (context->IsStackSlot()) {
517 __ mov(esi, ToOperand(context)); 524 __ mov(esi, ToOperand(context));
518 } else if (context->IsConstantOperand()) { 525 } else if (context->IsConstantOperand()) {
519 Handle<Object> literal = 526 Handle<Object> literal =
520 chunk_->LookupLiteral(LConstantOperand::cast(context)); 527 chunk_->LookupLiteral(LConstantOperand::cast(context));
521 LoadHeapObject(esi, Handle<Context>::cast(literal)); 528 __ LoadHeapObject(esi, Handle<Context>::cast(literal));
522 } else { 529 } else {
523 UNREACHABLE(); 530 UNREACHABLE();
524 } 531 }
525 532
526 __ CallRuntimeSaveDoubles(id); 533 __ CallRuntimeSaveDoubles(id);
527 RecordSafepointWithRegisters( 534 RecordSafepointWithRegisters(
528 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 535 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
529 } 536 }
530 537
531 538
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 } 1219 }
1213 } 1220 }
1214 } 1221 }
1215 } 1222 }
1216 1223
1217 1224
1218 void LCodeGen::DoConstantT(LConstantT* instr) { 1225 void LCodeGen::DoConstantT(LConstantT* instr) {
1219 Register reg = ToRegister(instr->result()); 1226 Register reg = ToRegister(instr->result());
1220 Handle<Object> handle = instr->value(); 1227 Handle<Object> handle = instr->value();
1221 if (handle->IsHeapObject()) { 1228 if (handle->IsHeapObject()) {
1222 LoadHeapObject(reg, Handle<HeapObject>::cast(handle)); 1229 __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle));
1223 } else { 1230 } else {
1224 __ Set(reg, Immediate(handle)); 1231 __ Set(reg, Immediate(handle));
1225 } 1232 }
1226 } 1233 }
1227 1234
1228 1235
1229 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1236 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1230 Register result = ToRegister(instr->result()); 1237 Register result = ToRegister(instr->result());
1231 Register array = ToRegister(instr->InputAt(0)); 1238 Register array = ToRegister(instr->InputAt(0));
1232 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); 1239 __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 flags = static_cast<InstanceofStub::Flags>( 2030 flags = static_cast<InstanceofStub::Flags>(
2024 flags | InstanceofStub::kReturnTrueFalseObject); 2031 flags | InstanceofStub::kReturnTrueFalseObject);
2025 InstanceofStub stub(flags); 2032 InstanceofStub stub(flags);
2026 2033
2027 // Get the temp register reserved by the instruction. This needs to be a 2034 // Get the temp register reserved by the instruction. This needs to be a
2028 // register which is pushed last by PushSafepointRegisters as top of the 2035 // register which is pushed last by PushSafepointRegisters as top of the
2029 // stack is used to pass the offset to the location of the map check to 2036 // stack is used to pass the offset to the location of the map check to
2030 // the stub. 2037 // the stub.
2031 Register temp = ToRegister(instr->TempAt(0)); 2038 Register temp = ToRegister(instr->TempAt(0));
2032 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); 2039 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0);
2033 __ mov(InstanceofStub::right(), Immediate(instr->function())); 2040 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2034 static const int kAdditionalDelta = 13; 2041 static const int kAdditionalDelta = 13;
2035 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2042 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2036 __ mov(temp, Immediate(delta)); 2043 __ mov(temp, Immediate(delta));
2037 __ StoreToSafepointRegisterSlot(temp, temp); 2044 __ StoreToSafepointRegisterSlot(temp, temp);
2038 CallCodeGeneric(stub.GetCode(), 2045 CallCodeGeneric(stub.GetCode(),
2039 RelocInfo::CODE_TARGET, 2046 RelocInfo::CODE_TARGET,
2040 instr, 2047 instr,
2041 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 2048 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
2042 ASSERT(instr->HasDeoptimizationEnvironment()); 2049 ASSERT(instr->HasDeoptimizationEnvironment());
2043 LEnvironment* env = instr->deoptimization_environment(); 2050 LEnvironment* env = instr->deoptimization_environment();
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2222 // Negative property indices are in-object properties, indexed 2229 // Negative property indices are in-object properties, indexed
2223 // from the end of the fixed part of the object. 2230 // from the end of the fixed part of the object.
2224 __ mov(result, FieldOperand(object, offset + type->instance_size())); 2231 __ mov(result, FieldOperand(object, offset + type->instance_size()));
2225 } else { 2232 } else {
2226 // Non-negative property indices are in the properties array. 2233 // Non-negative property indices are in the properties array.
2227 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2234 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
2228 __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); 2235 __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
2229 } 2236 }
2230 } else { 2237 } else {
2231 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); 2238 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
2232 LoadHeapObject(result, Handle<HeapObject>::cast(function)); 2239 __ LoadHeapObject(result, function);
2240 }
2241 }
2242
2243
2244 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
2245 ASSERT(!operand->IsDoubleRegister());
2246 if (operand->IsConstantOperand()) {
2247 Handle<Object> object = ToHandle(LConstantOperand::cast(operand));
2248 if (object->IsSmi()) {
2249 __ Push(Handle<Smi>::cast(object));
2250 } else {
2251 __ PushHeapObject(Handle<HeapObject>::cast(object));
2252 }
2253 } else if (operand->IsRegister()) {
2254 __ push(ToRegister(operand));
2255 } else {
2256 __ push(ToOperand(operand));
2233 } 2257 }
2234 } 2258 }
2235 2259
2236 2260
2237 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { 2261 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
2238 Register object = ToRegister(instr->object()); 2262 Register object = ToRegister(instr->object());
2239 Register result = ToRegister(instr->result()); 2263 Register result = ToRegister(instr->result());
2240 2264
2241 int map_count = instr->hydrogen()->types()->length(); 2265 int map_count = instr->hydrogen()->types()->length();
2242 Handle<String> name = instr->hydrogen()->name(); 2266 Handle<String> name = instr->hydrogen()->name();
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
2632 SafepointGenerator safepoint_generator( 2656 SafepointGenerator safepoint_generator(
2633 this, pointers, Safepoint::kLazyDeopt); 2657 this, pointers, Safepoint::kLazyDeopt);
2634 ParameterCount actual(eax); 2658 ParameterCount actual(eax);
2635 __ InvokeFunction(function, actual, CALL_FUNCTION, 2659 __ InvokeFunction(function, actual, CALL_FUNCTION,
2636 safepoint_generator, CALL_AS_METHOD); 2660 safepoint_generator, CALL_AS_METHOD);
2637 } 2661 }
2638 2662
2639 2663
2640 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2664 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2641 LOperand* argument = instr->InputAt(0); 2665 LOperand* argument = instr->InputAt(0);
2642 if (argument->IsConstantOperand()) { 2666 EmitPushTaggedOperand(argument);
2643 __ push(ToImmediate(argument));
2644 } else {
2645 __ push(ToOperand(argument));
2646 }
2647 } 2667 }
2648 2668
2649 2669
2650 void LCodeGen::DoThisFunction(LThisFunction* instr) { 2670 void LCodeGen::DoThisFunction(LThisFunction* instr) {
2651 Register result = ToRegister(instr->result()); 2671 Register result = ToRegister(instr->result());
2652 LoadHeapObject(result, instr->hydrogen()->closure()); 2672 __ LoadHeapObject(result, instr->hydrogen()->closure());
2653 } 2673 }
2654 2674
2655 2675
2656 void LCodeGen::DoContext(LContext* instr) { 2676 void LCodeGen::DoContext(LContext* instr) {
2657 Register result = ToRegister(instr->result()); 2677 Register result = ToRegister(instr->result());
2658 __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset)); 2678 __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset));
2659 } 2679 }
2660 2680
2661 2681
2662 void LCodeGen::DoOuterContext(LOuterContext* instr) { 2682 void LCodeGen::DoOuterContext(LOuterContext* instr) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2712 } else { 2732 } else {
2713 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); 2733 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset));
2714 } 2734 }
2715 2735
2716 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 2736 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
2717 } 2737 }
2718 2738
2719 2739
2720 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2740 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2721 ASSERT(ToRegister(instr->result()).is(eax)); 2741 ASSERT(ToRegister(instr->result()).is(eax));
2722 __ mov(edi, instr->function()); 2742 __ LoadHeapObject(edi, instr->function());
2723 CallKnownFunction(instr->function(), 2743 CallKnownFunction(instr->function(),
2724 instr->arity(), 2744 instr->arity(),
2725 instr, 2745 instr,
2726 CALL_AS_METHOD); 2746 CALL_AS_METHOD);
2727 } 2747 }
2728 2748
2729 2749
2730 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2750 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2731 Register input_reg = ToRegister(instr->value()); 2751 Register input_reg = ToRegister(instr->value());
2732 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 2752 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
3152 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; 3172 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
3153 Handle<Code> ic = 3173 Handle<Code> ic =
3154 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 3174 isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
3155 __ mov(ecx, instr->name()); 3175 __ mov(ecx, instr->name());
3156 CallCode(ic, mode, instr); 3176 CallCode(ic, mode, instr);
3157 } 3177 }
3158 3178
3159 3179
3160 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 3180 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
3161 ASSERT(ToRegister(instr->result()).is(eax)); 3181 ASSERT(ToRegister(instr->result()).is(eax));
3162 __ mov(edi, instr->target()); 3182 __ LoadHeapObject(edi, instr->target());
3163 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); 3183 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
3164 } 3184 }
3165 3185
3166 3186
3167 void LCodeGen::DoCallNew(LCallNew* instr) { 3187 void LCodeGen::DoCallNew(LCallNew* instr) {
3168 ASSERT(ToRegister(instr->context()).is(esi)); 3188 ASSERT(ToRegister(instr->context()).is(esi));
3169 ASSERT(ToRegister(instr->constructor()).is(edi)); 3189 ASSERT(ToRegister(instr->constructor()).is(edi));
3170 ASSERT(ToRegister(instr->result()).is(eax)); 3190 ASSERT(ToRegister(instr->result()).is(eax));
3171 3191
3172 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); 3192 Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
3517 3537
3518 3538
3519 void LCodeGen::DoStringLength(LStringLength* instr) { 3539 void LCodeGen::DoStringLength(LStringLength* instr) {
3520 Register string = ToRegister(instr->string()); 3540 Register string = ToRegister(instr->string());
3521 Register result = ToRegister(instr->result()); 3541 Register result = ToRegister(instr->result());
3522 __ mov(result, FieldOperand(string, String::kLengthOffset)); 3542 __ mov(result, FieldOperand(string, String::kLengthOffset));
3523 } 3543 }
3524 3544
3525 3545
3526 void LCodeGen::DoStringAdd(LStringAdd* instr) { 3546 void LCodeGen::DoStringAdd(LStringAdd* instr) {
3527 if (instr->left()->IsConstantOperand()) { 3547 EmitPushTaggedOperand(instr->left());
3528 __ push(ToImmediate(instr->left())); 3548 EmitPushTaggedOperand(instr->right());
3529 } else {
3530 __ push(ToOperand(instr->left()));
3531 }
3532 if (instr->right()->IsConstantOperand()) {
3533 __ push(ToImmediate(instr->right()));
3534 } else {
3535 __ push(ToOperand(instr->right()));
3536 }
3537 StringAddStub stub(NO_STRING_CHECK_IN_STUB); 3549 StringAddStub stub(NO_STRING_CHECK_IN_STUB);
3538 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 3550 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3539 } 3551 }
3540 3552
3541 3553
3542 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 3554 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
3543 LOperand* input = instr->InputAt(0); 3555 LOperand* input = instr->InputAt(0);
3544 ASSERT(input->IsRegister() || input->IsStackSlot()); 3556 ASSERT(input->IsRegister() || input->IsStackSlot());
3545 LOperand* output = instr->result(); 3557 LOperand* output = instr->result();
3546 ASSERT(output->IsDoubleRegister()); 3558 ASSERT(output->IsDoubleRegister());
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
4025 4037
4026 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 4038 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
4027 Handle<JSFunction> target = instr->hydrogen()->target(); 4039 Handle<JSFunction> target = instr->hydrogen()->target();
4028 if (isolate()->heap()->InNewSpace(*target)) { 4040 if (isolate()->heap()->InNewSpace(*target)) {
4029 Register reg = ToRegister(instr->value()); 4041 Register reg = ToRegister(instr->value());
4030 Handle<JSGlobalPropertyCell> cell = 4042 Handle<JSGlobalPropertyCell> cell =
4031 isolate()->factory()->NewJSGlobalPropertyCell(target); 4043 isolate()->factory()->NewJSGlobalPropertyCell(target);
4032 __ cmp(reg, Operand::Cell(cell)); 4044 __ cmp(reg, Operand::Cell(cell));
4033 } else { 4045 } else {
4034 Operand operand = ToOperand(instr->value()); 4046 Operand operand = ToOperand(instr->value());
4035 __ cmp(operand, instr->hydrogen()->target()); 4047 __ cmp(operand, target);
4036 } 4048 }
4037 DeoptimizeIf(not_equal, instr->environment()); 4049 DeoptimizeIf(not_equal, instr->environment());
4038 } 4050 }
4039 4051
4040 4052
4041 void LCodeGen::DoCheckMap(LCheckMap* instr) { 4053 void LCodeGen::DoCheckMap(LCheckMap* instr) {
4042 LOperand* input = instr->InputAt(0); 4054 LOperand* input = instr->InputAt(0);
4043 ASSERT(input->IsRegister()); 4055 ASSERT(input->IsRegister());
4044 Register reg = ToRegister(input); 4056 Register reg = ToRegister(input);
4045 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 4057 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4089 4101
4090 // smi 4102 // smi
4091 __ bind(&is_smi); 4103 __ bind(&is_smi);
4092 __ SmiUntag(input_reg); 4104 __ SmiUntag(input_reg);
4093 __ ClampUint8(input_reg); 4105 __ ClampUint8(input_reg);
4094 4106
4095 __ bind(&done); 4107 __ bind(&done);
4096 } 4108 }
4097 4109
4098 4110
4099 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) {
4100 if (isolate()->heap()->InNewSpace(*object)) {
4101 Handle<JSGlobalPropertyCell> cell =
4102 isolate()->factory()->NewJSGlobalPropertyCell(object);
4103 __ mov(result, Operand::Cell(cell));
4104 } else {
4105 __ mov(result, object);
4106 }
4107 }
4108
4109
4110 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 4111 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
4111 Register reg = ToRegister(instr->TempAt(0)); 4112 Register reg = ToRegister(instr->TempAt(0));
4112 4113
4113 Handle<JSObject> holder = instr->holder(); 4114 Handle<JSObject> holder = instr->holder();
4114 Handle<JSObject> current_prototype = instr->prototype(); 4115 Handle<JSObject> current_prototype = instr->prototype();
4115 4116
4116 // Load prototype object. 4117 // Load prototype object.
4117 LoadHeapObject(reg, current_prototype); 4118 __ LoadHeapObject(reg, current_prototype);
4118 4119
4119 // Check prototype maps up to the holder. 4120 // Check prototype maps up to the holder.
4120 while (!current_prototype.is_identical_to(holder)) { 4121 while (!current_prototype.is_identical_to(holder)) {
4121 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 4122 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
4122 Handle<Map>(current_prototype->map())); 4123 Handle<Map>(current_prototype->map()));
4123 DeoptimizeIf(not_equal, instr->environment()); 4124 DeoptimizeIf(not_equal, instr->environment());
4124 current_prototype = 4125 current_prototype =
4125 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); 4126 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
4126 // Load next prototype object. 4127 // Load next prototype object.
4127 LoadHeapObject(reg, current_prototype); 4128 __ LoadHeapObject(reg, current_prototype);
4128 } 4129 }
4129 4130
4130 // Check the holder map. 4131 // Check the holder map.
4131 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 4132 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
4132 Handle<Map>(current_prototype->map())); 4133 Handle<Map>(current_prototype->map()));
4133 DeoptimizeIf(not_equal, instr->environment()); 4134 DeoptimizeIf(not_equal, instr->environment());
4134 } 4135 }
4135 4136
4136 4137
4137 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 4138 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4172 4173
4173 4174
4174 void LCodeGen::EmitDeepCopy(Handle<JSObject> object, 4175 void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
4175 Register result, 4176 Register result,
4176 Register source, 4177 Register source,
4177 int* offset) { 4178 int* offset) {
4178 ASSERT(!source.is(ecx)); 4179 ASSERT(!source.is(ecx));
4179 ASSERT(!result.is(ecx)); 4180 ASSERT(!result.is(ecx));
4180 4181
4181 if (FLAG_debug_code) { 4182 if (FLAG_debug_code) {
4182 LoadHeapObject(ecx, object); 4183 __ LoadHeapObject(ecx, object);
4183 __ cmp(source, ecx); 4184 __ cmp(source, ecx);
4184 __ Assert(equal, "Unexpected object literal boilerplate"); 4185 __ Assert(equal, "Unexpected object literal boilerplate");
4185 } 4186 }
4186 4187
4187 // Increase the offset so that subsequent objects end up right after 4188 // Increase the offset so that subsequent objects end up right after
4188 // this one. 4189 // this one.
4189 int current_offset = *offset; 4190 int current_offset = *offset;
4190 int size = object->map()->instance_size(); 4191 int size = object->map()->instance_size();
4191 *offset += size; 4192 *offset += size;
4192 4193
4193 // Copy object header. 4194 // Copy object header.
4194 ASSERT(object->properties()->length() == 0); 4195 ASSERT(object->properties()->length() == 0);
4195 ASSERT(object->elements()->length() == 0 || 4196 ASSERT(object->elements()->length() == 0 ||
4196 object->elements()->map() == isolate()->heap()->fixed_cow_array_map()); 4197 object->elements()->map() == isolate()->heap()->fixed_cow_array_map());
4197 int inobject_properties = object->map()->inobject_properties(); 4198 int inobject_properties = object->map()->inobject_properties();
4198 int header_size = size - inobject_properties * kPointerSize; 4199 int header_size = size - inobject_properties * kPointerSize;
4199 for (int i = 0; i < header_size; i += kPointerSize) { 4200 for (int i = 0; i < header_size; i += kPointerSize) {
4200 __ mov(ecx, FieldOperand(source, i)); 4201 __ mov(ecx, FieldOperand(source, i));
4201 __ mov(FieldOperand(result, current_offset + i), ecx); 4202 __ mov(FieldOperand(result, current_offset + i), ecx);
4202 } 4203 }
4203 4204
4204 // Copy in-object properties. 4205 // Copy in-object properties.
4205 for (int i = 0; i < inobject_properties; i++) { 4206 for (int i = 0; i < inobject_properties; i++) {
4206 int total_offset = current_offset + object->GetInObjectPropertyOffset(i); 4207 int total_offset = current_offset + object->GetInObjectPropertyOffset(i);
4207 Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); 4208 Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i));
4208 if (value->IsJSObject()) { 4209 if (value->IsJSObject()) {
4209 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 4210 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
4210 __ lea(ecx, Operand(result, *offset)); 4211 __ lea(ecx, Operand(result, *offset));
4211 __ mov(FieldOperand(result, total_offset), ecx); 4212 __ mov(FieldOperand(result, total_offset), ecx);
4212 LoadHeapObject(source, value_object); 4213 __ LoadHeapObject(source, value_object);
4213 EmitDeepCopy(value_object, result, source, offset); 4214 EmitDeepCopy(value_object, result, source, offset);
4214 } else if (value->IsHeapObject()) { 4215 } else if (value->IsHeapObject()) {
4215 LoadHeapObject(ecx, Handle<HeapObject>::cast(value)); 4216 __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value));
4216 __ mov(FieldOperand(result, total_offset), ecx); 4217 __ mov(FieldOperand(result, total_offset), ecx);
4217 } else { 4218 } else {
4218 __ mov(FieldOperand(result, total_offset), Immediate(value)); 4219 __ mov(FieldOperand(result, total_offset), Immediate(value));
4219 } 4220 }
4220 } 4221 }
4221 } 4222 }
4222 4223
4223 4224
4224 void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) { 4225 void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) {
4225 ASSERT(ToRegister(instr->context()).is(esi)); 4226 ASSERT(ToRegister(instr->context()).is(esi));
4226 int size = instr->hydrogen()->total_size(); 4227 int size = instr->hydrogen()->total_size();
4227 4228
4228 // Allocate all objects that are part of the literal in one big 4229 // Allocate all objects that are part of the literal in one big
4229 // allocation. This avoids multiple limit checks. 4230 // allocation. This avoids multiple limit checks.
4230 Label allocated, runtime_allocate; 4231 Label allocated, runtime_allocate;
4231 __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); 4232 __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
4232 __ jmp(&allocated); 4233 __ jmp(&allocated);
4233 4234
4234 __ bind(&runtime_allocate); 4235 __ bind(&runtime_allocate);
4235 __ push(Immediate(Smi::FromInt(size))); 4236 __ push(Immediate(Smi::FromInt(size)));
4236 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 4237 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
4237 4238
4238 __ bind(&allocated); 4239 __ bind(&allocated);
4239 int offset = 0; 4240 int offset = 0;
4240 LoadHeapObject(ebx, instr->hydrogen()->boilerplate()); 4241 __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate());
4241 EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset); 4242 EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset);
4242 ASSERT_EQ(size, offset); 4243 ASSERT_EQ(size, offset);
4243 } 4244 }
4244 4245
4245 4246
4246 void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) { 4247 void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
4247 ASSERT(ToRegister(instr->context()).is(esi)); 4248 ASSERT(ToRegister(instr->context()).is(esi));
4248 Handle<FixedArray> constant_properties = 4249 Handle<FixedArray> constant_properties =
4249 instr->hydrogen()->constant_properties(); 4250 instr->hydrogen()->constant_properties();
4250 4251
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4352 __ push(Immediate(pretenure 4353 __ push(Immediate(pretenure
4353 ? factory()->true_value() 4354 ? factory()->true_value()
4354 : factory()->false_value())); 4355 : factory()->false_value()));
4355 CallRuntime(Runtime::kNewClosure, 3, instr); 4356 CallRuntime(Runtime::kNewClosure, 3, instr);
4356 } 4357 }
4357 } 4358 }
4358 4359
4359 4360
4360 void LCodeGen::DoTypeof(LTypeof* instr) { 4361 void LCodeGen::DoTypeof(LTypeof* instr) {
4361 LOperand* input = instr->InputAt(1); 4362 LOperand* input = instr->InputAt(1);
4362 if (input->IsConstantOperand()) { 4363 EmitPushTaggedOperand(input);
4363 __ push(ToImmediate(input));
4364 } else {
4365 __ push(ToOperand(input));
4366 }
4367 CallRuntime(Runtime::kTypeof, 1, instr); 4364 CallRuntime(Runtime::kTypeof, 1, instr);
4368 } 4365 }
4369 4366
4370 4367
4371 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 4368 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
4372 Register input = ToRegister(instr->InputAt(0)); 4369 Register input = ToRegister(instr->InputAt(0));
4373 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4370 int true_block = chunk_->LookupDestination(instr->true_block_id());
4374 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4371 int false_block = chunk_->LookupDestination(instr->false_block_id());
4375 Label* true_label = chunk_->GetAssemblyLabel(true_block); 4372 Label* true_label = chunk_->GetAssemblyLabel(true_block);
4376 Label* false_label = chunk_->GetAssemblyLabel(false_block); 4373 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4506 4503
4507 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 4504 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
4508 DeoptimizeIf(no_condition, instr->environment()); 4505 DeoptimizeIf(no_condition, instr->environment());
4509 } 4506 }
4510 4507
4511 4508
4512 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { 4509 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
4513 LOperand* obj = instr->object(); 4510 LOperand* obj = instr->object();
4514 LOperand* key = instr->key(); 4511 LOperand* key = instr->key();
4515 __ push(ToOperand(obj)); 4512 __ push(ToOperand(obj));
4516 if (key->IsConstantOperand()) { 4513 EmitPushTaggedOperand(key);
4517 __ push(ToImmediate(key));
4518 } else {
4519 __ push(ToOperand(key));
4520 }
4521 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 4514 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
4522 LPointerMap* pointers = instr->pointer_map(); 4515 LPointerMap* pointers = instr->pointer_map();
4523 RecordPosition(pointers->position()); 4516 RecordPosition(pointers->position());
4524 // Create safepoint generator that will also ensure enough space in the 4517 // Create safepoint generator that will also ensure enough space in the
4525 // reloc info for patching in deoptimization (since this is invoking a 4518 // reloc info for patching in deoptimization (since this is invoking a
4526 // builtin) 4519 // builtin)
4527 SafepointGenerator safepoint_generator( 4520 SafepointGenerator safepoint_generator(
4528 this, pointers, Safepoint::kLazyDeopt); 4521 this, pointers, Safepoint::kLazyDeopt);
4529 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 4522 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
4530 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); 4523 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4587 ASSERT(!environment->HasBeenRegistered()); 4580 ASSERT(!environment->HasBeenRegistered());
4588 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 4581 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
4589 ASSERT(osr_pc_offset_ == -1); 4582 ASSERT(osr_pc_offset_ == -1);
4590 osr_pc_offset_ = masm()->pc_offset(); 4583 osr_pc_offset_ = masm()->pc_offset();
4591 } 4584 }
4592 4585
4593 4586
4594 void LCodeGen::DoIn(LIn* instr) { 4587 void LCodeGen::DoIn(LIn* instr) {
4595 LOperand* obj = instr->object(); 4588 LOperand* obj = instr->object();
4596 LOperand* key = instr->key(); 4589 LOperand* key = instr->key();
4597 if (key->IsConstantOperand()) { 4590 EmitPushTaggedOperand(key);
4598 __ push(ToImmediate(key)); 4591 EmitPushTaggedOperand(obj);
4599 } else {
4600 __ push(ToOperand(key));
4601 }
4602 if (obj->IsConstantOperand()) {
4603 __ push(ToImmediate(obj));
4604 } else {
4605 __ push(ToOperand(obj));
4606 }
4607 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 4592 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
4608 LPointerMap* pointers = instr->pointer_map(); 4593 LPointerMap* pointers = instr->pointer_map();
4609 RecordPosition(pointers->position()); 4594 RecordPosition(pointers->position());
4610 SafepointGenerator safepoint_generator( 4595 SafepointGenerator safepoint_generator(
4611 this, pointers, Safepoint::kLazyDeopt); 4596 this, pointers, Safepoint::kLazyDeopt);
4612 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4597 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4613 } 4598 }
4614 4599
4615 4600
4616 #undef __ 4601 #undef __
4617 4602
4618 } } // namespace v8::internal 4603 } } // namespace v8::internal
4619 4604
4620 #endif // V8_TARGET_ARCH_IA32 4605 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698