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 |