| 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 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 Register LCodeGen::ToRegister(LOperand* op) const { | 345 Register LCodeGen::ToRegister(LOperand* op) const { |
| 346 ASSERT(op->IsRegister()); | 346 ASSERT(op->IsRegister()); |
| 347 return ToRegister(op->index()); | 347 return ToRegister(op->index()); |
| 348 } | 348 } |
| 349 | 349 |
| 350 | 350 |
| 351 Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) { | 351 Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) { |
| 352 if (op->IsRegister()) { | 352 if (op->IsRegister()) { |
| 353 return ToRegister(op->index()); | 353 return ToRegister(op->index()); |
| 354 } else if (op->IsConstantOperand()) { | 354 } else if (op->IsConstantOperand()) { |
| 355 __ mov(scratch, ToOperand(op)); | 355 LConstantOperand* const_op = LConstantOperand::cast(op); |
| 356 Handle<Object> literal = chunk_->LookupLiteral(const_op); |
| 357 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 358 if (r.IsInteger32()) { |
| 359 ASSERT(literal->IsNumber()); |
| 360 __ mov(scratch, Operand(static_cast<int32_t>(literal->Number()))); |
| 361 } else if (r.IsDouble()) { |
| 362 Abort("EmitLoadRegister: Unsupported double immediate."); |
| 363 } else { |
| 364 ASSERT(r.IsTagged()); |
| 365 if (literal->IsSmi()) { |
| 366 __ mov(scratch, Operand(literal)); |
| 367 } else { |
| 368 __ LoadHeapObject(scratch, Handle<HeapObject>::cast(literal)); |
| 369 } |
| 370 } |
| 356 return scratch; | 371 return scratch; |
| 357 } else if (op->IsStackSlot() || op->IsArgument()) { | 372 } else if (op->IsStackSlot() || op->IsArgument()) { |
| 358 __ ldr(scratch, ToMemOperand(op)); | 373 __ ldr(scratch, ToMemOperand(op)); |
| 359 return scratch; | 374 return scratch; |
| 360 } | 375 } |
| 361 UNREACHABLE(); | 376 UNREACHABLE(); |
| 362 return scratch; | 377 return scratch; |
| 363 } | 378 } |
| 364 | 379 |
| 365 | 380 |
| (...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1370 | 1385 |
| 1371 void LCodeGen::DoConstantD(LConstantD* instr) { | 1386 void LCodeGen::DoConstantD(LConstantD* instr) { |
| 1372 ASSERT(instr->result()->IsDoubleRegister()); | 1387 ASSERT(instr->result()->IsDoubleRegister()); |
| 1373 DwVfpRegister result = ToDoubleRegister(instr->result()); | 1388 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 1374 double v = instr->value(); | 1389 double v = instr->value(); |
| 1375 __ Vmov(result, v); | 1390 __ Vmov(result, v); |
| 1376 } | 1391 } |
| 1377 | 1392 |
| 1378 | 1393 |
| 1379 void LCodeGen::DoConstantT(LConstantT* instr) { | 1394 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1380 ASSERT(instr->result()->IsRegister()); | 1395 Handle<Object> value = instr->value(); |
| 1381 __ mov(ToRegister(instr->result()), Operand(instr->value())); | 1396 if (value->IsSmi()) { |
| 1397 __ mov(ToRegister(instr->result()), Operand(value)); |
| 1398 } else { |
| 1399 __ LoadHeapObject(ToRegister(instr->result()), |
| 1400 Handle<HeapObject>::cast(value)); |
| 1401 } |
| 1382 } | 1402 } |
| 1383 | 1403 |
| 1384 | 1404 |
| 1385 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { | 1405 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { |
| 1386 Register result = ToRegister(instr->result()); | 1406 Register result = ToRegister(instr->result()); |
| 1387 Register array = ToRegister(instr->InputAt(0)); | 1407 Register array = ToRegister(instr->InputAt(0)); |
| 1388 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); | 1408 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); |
| 1389 } | 1409 } |
| 1390 | 1410 |
| 1391 | 1411 |
| (...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2123 flags | InstanceofStub::kReturnTrueFalseObject); | 2143 flags | InstanceofStub::kReturnTrueFalseObject); |
| 2124 InstanceofStub stub(flags); | 2144 InstanceofStub stub(flags); |
| 2125 | 2145 |
| 2126 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 2146 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
| 2127 | 2147 |
| 2128 // Get the temp register reserved by the instruction. This needs to be r4 as | 2148 // Get the temp register reserved by the instruction. This needs to be r4 as |
| 2129 // its slot of the pushing of safepoint registers is used to communicate the | 2149 // its slot of the pushing of safepoint registers is used to communicate the |
| 2130 // offset to the location of the map check. | 2150 // offset to the location of the map check. |
| 2131 Register temp = ToRegister(instr->TempAt(0)); | 2151 Register temp = ToRegister(instr->TempAt(0)); |
| 2132 ASSERT(temp.is(r4)); | 2152 ASSERT(temp.is(r4)); |
| 2133 __ mov(InstanceofStub::right(), Operand(instr->function())); | 2153 __ LoadHeapObject(InstanceofStub::right(), instr->function()); |
| 2134 static const int kAdditionalDelta = 4; | 2154 static const int kAdditionalDelta = 4; |
| 2135 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; | 2155 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; |
| 2136 Label before_push_delta; | 2156 Label before_push_delta; |
| 2137 __ bind(&before_push_delta); | 2157 __ bind(&before_push_delta); |
| 2138 __ BlockConstPoolFor(kAdditionalDelta); | 2158 __ BlockConstPoolFor(kAdditionalDelta); |
| 2139 __ mov(temp, Operand(delta * kPointerSize)); | 2159 __ mov(temp, Operand(delta * kPointerSize)); |
| 2140 __ StoreToSafepointRegisterSlot(temp, temp); | 2160 __ StoreToSafepointRegisterSlot(temp, temp); |
| 2141 CallCodeGeneric(stub.GetCode(), | 2161 CallCodeGeneric(stub.GetCode(), |
| 2142 RelocInfo::CODE_TARGET, | 2162 RelocInfo::CODE_TARGET, |
| 2143 instr, | 2163 instr, |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2323 // Negative property indices are in-object properties, indexed | 2343 // Negative property indices are in-object properties, indexed |
| 2324 // from the end of the fixed part of the object. | 2344 // from the end of the fixed part of the object. |
| 2325 __ ldr(result, FieldMemOperand(object, offset + type->instance_size())); | 2345 __ ldr(result, FieldMemOperand(object, offset + type->instance_size())); |
| 2326 } else { | 2346 } else { |
| 2327 // Non-negative property indices are in the properties array. | 2347 // Non-negative property indices are in the properties array. |
| 2328 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 2348 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 2329 __ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize)); | 2349 __ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize)); |
| 2330 } | 2350 } |
| 2331 } else { | 2351 } else { |
| 2332 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); | 2352 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); |
| 2333 LoadHeapObject(result, Handle<HeapObject>::cast(function)); | 2353 __ LoadHeapObject(result, function); |
| 2334 } | 2354 } |
| 2335 } | 2355 } |
| 2336 | 2356 |
| 2337 | 2357 |
| 2338 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { | 2358 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { |
| 2339 Register object = ToRegister(instr->object()); | 2359 Register object = ToRegister(instr->object()); |
| 2340 Register result = ToRegister(instr->result()); | 2360 Register result = ToRegister(instr->result()); |
| 2341 Register scratch = scratch0(); | 2361 Register scratch = scratch0(); |
| 2342 int map_count = instr->hydrogen()->types()->length(); | 2362 int map_count = instr->hydrogen()->types()->length(); |
| 2343 Handle<String> name = instr->hydrogen()->name(); | 2363 Handle<String> name = instr->hydrogen()->name(); |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2839 // Setup deoptimization. | 2859 // Setup deoptimization. |
| 2840 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); | 2860 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); |
| 2841 | 2861 |
| 2842 // Restore context. | 2862 // Restore context. |
| 2843 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2863 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2844 } | 2864 } |
| 2845 | 2865 |
| 2846 | 2866 |
| 2847 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2867 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 2848 ASSERT(ToRegister(instr->result()).is(r0)); | 2868 ASSERT(ToRegister(instr->result()).is(r0)); |
| 2849 __ mov(r1, Operand(instr->function())); | 2869 __ LoadHeapObject(r1, instr->function()); |
| 2850 CallKnownFunction(instr->function(), | 2870 CallKnownFunction(instr->function(), |
| 2851 instr->arity(), | 2871 instr->arity(), |
| 2852 instr, | 2872 instr, |
| 2853 CALL_AS_METHOD); | 2873 CALL_AS_METHOD); |
| 2854 } | 2874 } |
| 2855 | 2875 |
| 2856 | 2876 |
| 2857 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2877 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
| 2858 Register input = ToRegister(instr->InputAt(0)); | 2878 Register input = ToRegister(instr->InputAt(0)); |
| 2859 Register result = ToRegister(instr->result()); | 2879 Register result = ToRegister(instr->result()); |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3256 Handle<Code> ic = | 3276 Handle<Code> ic = |
| 3257 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3277 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
| 3258 __ mov(r2, Operand(instr->name())); | 3278 __ mov(r2, Operand(instr->name())); |
| 3259 CallCode(ic, mode, instr); | 3279 CallCode(ic, mode, instr); |
| 3260 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3280 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3261 } | 3281 } |
| 3262 | 3282 |
| 3263 | 3283 |
| 3264 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3284 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
| 3265 ASSERT(ToRegister(instr->result()).is(r0)); | 3285 ASSERT(ToRegister(instr->result()).is(r0)); |
| 3266 __ mov(r1, Operand(instr->target())); | 3286 __ LoadHeapObject(r1, instr->target()); |
| 3267 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); | 3287 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
| 3268 } | 3288 } |
| 3269 | 3289 |
| 3270 | 3290 |
| 3271 void LCodeGen::DoCallNew(LCallNew* instr) { | 3291 void LCodeGen::DoCallNew(LCallNew* instr) { |
| 3272 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); | 3292 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); |
| 3273 ASSERT(ToRegister(instr->result()).is(r0)); | 3293 ASSERT(ToRegister(instr->result()).is(r0)); |
| 3274 | 3294 |
| 3275 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3295 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
| 3276 __ mov(r0, Operand(instr->arity())); | 3296 __ mov(r0, Operand(instr->arity())); |
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4083 } else { | 4103 } else { |
| 4084 __ and_(scratch, scratch, Operand(mask)); | 4104 __ and_(scratch, scratch, Operand(mask)); |
| 4085 __ cmp(scratch, Operand(tag)); | 4105 __ cmp(scratch, Operand(tag)); |
| 4086 DeoptimizeIf(ne, instr->environment()); | 4106 DeoptimizeIf(ne, instr->environment()); |
| 4087 } | 4107 } |
| 4088 } | 4108 } |
| 4089 } | 4109 } |
| 4090 | 4110 |
| 4091 | 4111 |
| 4092 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 4112 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
| 4093 ASSERT(instr->InputAt(0)->IsRegister()); | 4113 Register reg = ToRegister(instr->value()); |
| 4094 Register reg = ToRegister(instr->InputAt(0)); | 4114 Handle<JSFunction> target = instr->hydrogen()->target(); |
| 4095 __ cmp(reg, Operand(instr->hydrogen()->target())); | 4115 if (isolate()->heap()->InNewSpace(*target)) { |
| 4116 Register reg = ToRegister(instr->value()); |
| 4117 Handle<JSGlobalPropertyCell> cell = |
| 4118 isolate()->factory()->NewJSGlobalPropertyCell(target); |
| 4119 __ mov(ip, Operand(Handle<Object>(cell))); |
| 4120 __ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); |
| 4121 __ cmp(reg, ip); |
| 4122 } else { |
| 4123 __ cmp(reg, Operand(target)); |
| 4124 } |
| 4096 DeoptimizeIf(ne, instr->environment()); | 4125 DeoptimizeIf(ne, instr->environment()); |
| 4097 } | 4126 } |
| 4098 | 4127 |
| 4099 | 4128 |
| 4100 void LCodeGen::DoCheckMap(LCheckMap* instr) { | 4129 void LCodeGen::DoCheckMap(LCheckMap* instr) { |
| 4101 Register scratch = scratch0(); | 4130 Register scratch = scratch0(); |
| 4102 LOperand* input = instr->InputAt(0); | 4131 LOperand* input = instr->InputAt(0); |
| 4103 ASSERT(input->IsRegister()); | 4132 ASSERT(input->IsRegister()); |
| 4104 Register reg = ToRegister(input); | 4133 Register reg = ToRegister(input); |
| 4105 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 4134 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4154 | 4183 |
| 4155 // smi | 4184 // smi |
| 4156 __ bind(&is_smi); | 4185 __ bind(&is_smi); |
| 4157 __ SmiUntag(result_reg, input_reg); | 4186 __ SmiUntag(result_reg, input_reg); |
| 4158 __ ClampUint8(result_reg, result_reg); | 4187 __ ClampUint8(result_reg, result_reg); |
| 4159 | 4188 |
| 4160 __ bind(&done); | 4189 __ bind(&done); |
| 4161 } | 4190 } |
| 4162 | 4191 |
| 4163 | 4192 |
| 4164 void LCodeGen::LoadHeapObject(Register result, | |
| 4165 Handle<HeapObject> object) { | |
| 4166 if (heap()->InNewSpace(*object)) { | |
| 4167 Handle<JSGlobalPropertyCell> cell = | |
| 4168 factory()->NewJSGlobalPropertyCell(object); | |
| 4169 __ mov(result, Operand(cell)); | |
| 4170 __ ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset)); | |
| 4171 } else { | |
| 4172 __ mov(result, Operand(object)); | |
| 4173 } | |
| 4174 } | |
| 4175 | |
| 4176 | |
| 4177 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { | 4193 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { |
| 4178 Register temp1 = ToRegister(instr->TempAt(0)); | 4194 Register temp1 = ToRegister(instr->TempAt(0)); |
| 4179 Register temp2 = ToRegister(instr->TempAt(1)); | 4195 Register temp2 = ToRegister(instr->TempAt(1)); |
| 4180 | 4196 |
| 4181 Handle<JSObject> holder = instr->holder(); | 4197 Handle<JSObject> holder = instr->holder(); |
| 4182 Handle<JSObject> current_prototype = instr->prototype(); | 4198 Handle<JSObject> current_prototype = instr->prototype(); |
| 4183 | 4199 |
| 4184 // Load prototype object. | 4200 // Load prototype object. |
| 4185 LoadHeapObject(temp1, current_prototype); | 4201 __ LoadHeapObject(temp1, current_prototype); |
| 4186 | 4202 |
| 4187 // Check prototype maps up to the holder. | 4203 // Check prototype maps up to the holder. |
| 4188 while (!current_prototype.is_identical_to(holder)) { | 4204 while (!current_prototype.is_identical_to(holder)) { |
| 4189 __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset)); | 4205 __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset)); |
| 4190 __ cmp(temp2, Operand(Handle<Map>(current_prototype->map()))); | 4206 __ cmp(temp2, Operand(Handle<Map>(current_prototype->map()))); |
| 4191 DeoptimizeIf(ne, instr->environment()); | 4207 DeoptimizeIf(ne, instr->environment()); |
| 4192 current_prototype = | 4208 current_prototype = |
| 4193 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); | 4209 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); |
| 4194 // Load next prototype object. | 4210 // Load next prototype object. |
| 4195 LoadHeapObject(temp1, current_prototype); | 4211 __ LoadHeapObject(temp1, current_prototype); |
| 4196 } | 4212 } |
| 4197 | 4213 |
| 4198 // Check the holder map. | 4214 // Check the holder map. |
| 4199 __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset)); | 4215 __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset)); |
| 4200 __ cmp(temp2, Operand(Handle<Map>(current_prototype->map()))); | 4216 __ cmp(temp2, Operand(Handle<Map>(current_prototype->map()))); |
| 4201 DeoptimizeIf(ne, instr->environment()); | 4217 DeoptimizeIf(ne, instr->environment()); |
| 4202 } | 4218 } |
| 4203 | 4219 |
| 4204 | 4220 |
| 4205 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 4221 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4566 ASSERT(osr_pc_offset_ == -1); | 4582 ASSERT(osr_pc_offset_ == -1); |
| 4567 osr_pc_offset_ = masm()->pc_offset(); | 4583 osr_pc_offset_ = masm()->pc_offset(); |
| 4568 } | 4584 } |
| 4569 | 4585 |
| 4570 | 4586 |
| 4571 | 4587 |
| 4572 | 4588 |
| 4573 #undef __ | 4589 #undef __ |
| 4574 | 4590 |
| 4575 } } // namespace v8::internal | 4591 } } // namespace v8::internal |
| OLD | NEW |