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

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

Issue 12385014: Hydrogen stubs for array constructors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: With all ports done Created 7 years, 8 months 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 18 matching lines...) Expand all
29 29
30 #include "arm/lithium-codegen-arm.h" 30 #include "arm/lithium-codegen-arm.h"
31 #include "arm/lithium-gap-resolver-arm.h" 31 #include "arm/lithium-gap-resolver-arm.h"
32 #include "code-stubs.h" 32 #include "code-stubs.h"
33 #include "stub-cache.h" 33 #include "stub-cache.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 38
39 static SaveFPRegsMode GetSaveFPRegsMode() {
40 // We don't need to save floating point regs when generating the snapshot
41 return !Serializer::enabled() ? kSaveFPRegs : kDontSaveFPRegs;
42 }
43
44
39 class SafepointGenerator : public CallWrapper { 45 class SafepointGenerator : public CallWrapper {
40 public: 46 public:
41 SafepointGenerator(LCodeGen* codegen, 47 SafepointGenerator(LCodeGen* codegen,
42 LPointerMap* pointers, 48 LPointerMap* pointers,
43 Safepoint::DeoptMode mode) 49 Safepoint::DeoptMode mode)
44 : codegen_(codegen), 50 : codegen_(codegen),
45 pointers_(pointers), 51 pointers_(pointers),
46 deopt_mode_(mode) { } 52 deopt_mode_(mode) { }
47 virtual ~SafepointGenerator() { } 53 virtual ~SafepointGenerator() { }
48 54
(...skipping 2887 matching lines...) Expand 10 before | Expand all | Expand 10 after
2936 while (!save_iterator.Done()) { 2942 while (!save_iterator.Done()) {
2937 __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), 2943 __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
2938 MemOperand(sp, count * kDoubleSize)); 2944 MemOperand(sp, count * kDoubleSize));
2939 save_iterator.Advance(); 2945 save_iterator.Advance();
2940 count++; 2946 count++;
2941 } 2947 }
2942 } 2948 }
2943 if (NeedsEagerFrame()) { 2949 if (NeedsEagerFrame()) {
2944 __ mov(sp, fp); 2950 __ mov(sp, fp);
2945 __ ldm(ia_w, sp, fp.bit() | lr.bit()); 2951 __ ldm(ia_w, sp, fp.bit() | lr.bit());
2952 }
2953 if (instr->has_constant_parameter_count()) {
2954 int parameter_count = ToInteger32(instr->constant_parameter_count());
2955 int32_t sp_delta = (parameter_count + 1) * kPointerSize;
2956 if (sp_delta != 0) {
2957 __ add(sp, sp, Operand(sp_delta));
2958 }
2959 } else {
2960 Register reg = ToRegister(instr->parameter_count());
2961 __ SmiUntag(reg); // it is a smi
2962 __ add(sp, sp, Operand(reg, LSL, kPointerSizeLog2));
2963 }
2946 2964
2947 if (instr->has_constant_parameter_count()) {
2948 int parameter_count = ToInteger32(instr->constant_parameter_count());
2949 int32_t sp_delta = (parameter_count + 1) * kPointerSize;
2950 if (sp_delta != 0) {
2951 __ add(sp, sp, Operand(sp_delta));
2952 }
2953 } else {
2954 Register reg = ToRegister(instr->parameter_count());
2955 __ add(reg, reg, Operand(1));
2956 __ add(sp, sp, Operand(reg, LSL, kPointerSizeLog2));
2957 }
2958 }
2959 __ Jump(lr); 2965 __ Jump(lr);
2960 } 2966 }
2961 2967
2962 2968
2963 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2969 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2964 Register result = ToRegister(instr->result()); 2970 Register result = ToRegister(instr->result());
2965 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell()))); 2971 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell())));
2966 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); 2972 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
2967 if (instr->hydrogen()->RequiresHoleCheck()) { 2973 if (instr->hydrogen()->RequiresHoleCheck()) {
2968 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 2974 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3059 __ str(value, target); 3065 __ str(value, target);
3060 if (instr->hydrogen()->NeedsWriteBarrier()) { 3066 if (instr->hydrogen()->NeedsWriteBarrier()) {
3061 HType type = instr->hydrogen()->value()->type(); 3067 HType type = instr->hydrogen()->value()->type();
3062 SmiCheck check_needed = 3068 SmiCheck check_needed =
3063 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3069 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3064 __ RecordWriteContextSlot(context, 3070 __ RecordWriteContextSlot(context,
3065 target.offset(), 3071 target.offset(),
3066 value, 3072 value,
3067 scratch, 3073 scratch,
3068 GetLinkRegisterState(), 3074 GetLinkRegisterState(),
3069 kSaveFPRegs, 3075 GetSaveFPRegsMode(),
3070 EMIT_REMEMBERED_SET, 3076 EMIT_REMEMBERED_SET,
3071 check_needed); 3077 check_needed);
3072 } 3078 }
3073 3079
3074 __ bind(&skip_assignment); 3080 __ bind(&skip_assignment);
3075 } 3081 }
3076 3082
3077 3083
3078 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 3084 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
3079 Register object = ToRegister(instr->object()); 3085 Register object = ToRegister(instr->object());
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 LLoadExternalArrayPointer* instr) { 3272 LLoadExternalArrayPointer* instr) {
3267 Register to_reg = ToRegister(instr->result()); 3273 Register to_reg = ToRegister(instr->result());
3268 Register from_reg = ToRegister(instr->object()); 3274 Register from_reg = ToRegister(instr->object());
3269 __ ldr(to_reg, FieldMemOperand(from_reg, 3275 __ ldr(to_reg, FieldMemOperand(from_reg,
3270 ExternalArray::kExternalPointerOffset)); 3276 ExternalArray::kExternalPointerOffset));
3271 } 3277 }
3272 3278
3273 3279
3274 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 3280 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3275 Register arguments = ToRegister(instr->arguments()); 3281 Register arguments = ToRegister(instr->arguments());
3276 Register length = ToRegister(instr->length());
3277 Register index = ToRegister(instr->index());
3278 Register result = ToRegister(instr->result()); 3282 Register result = ToRegister(instr->result());
3279 // There are two words between the frame pointer and the last argument. 3283 if (instr->length()->IsConstantOperand() &&
3280 // Subtracting from length accounts for one of them add one more. 3284 instr->index()->IsConstantOperand()) {
3281 __ sub(length, length, index); 3285 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3282 __ add(length, length, Operand(1)); 3286 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3283 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); 3287 int index = (const_length - const_index) + 1;
3288 __ ldr(result, MemOperand(arguments, index * kPointerSize));
3289 } else {
3290 Register length = ToRegister(instr->length());
3291 Register index = ToRegister(instr->index());
3292 // There are two words between the frame pointer and the last argument.
3293 // Subtracting from length accounts for one of them add one more.
3294 __ sub(length, length, index);
3295 __ add(length, length, Operand(1));
3296 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
3297 }
3284 } 3298 }
3285 3299
3286 3300
3287 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3301 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3288 Register external_pointer = ToRegister(instr->elements()); 3302 Register external_pointer = ToRegister(instr->elements());
3289 Register key = no_reg; 3303 Register key = no_reg;
3290 ElementsKind elements_kind = instr->elements_kind(); 3304 ElementsKind elements_kind = instr->elements_kind();
3291 bool key_is_constant = instr->key()->IsConstantOperand(); 3305 bool key_is_constant = instr->key()->IsConstantOperand();
3292 int constant_key = 0; 3306 int constant_key = 0;
3293 if (key_is_constant) { 3307 if (key_is_constant) {
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
4210 } 4224 }
4211 4225
4212 4226
4213 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { 4227 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4214 ASSERT(ToRegister(instr->constructor()).is(r1)); 4228 ASSERT(ToRegister(instr->constructor()).is(r1));
4215 ASSERT(ToRegister(instr->result()).is(r0)); 4229 ASSERT(ToRegister(instr->result()).is(r0));
4216 ASSERT(FLAG_optimize_constructed_arrays); 4230 ASSERT(FLAG_optimize_constructed_arrays);
4217 4231
4218 __ mov(r0, Operand(instr->arity())); 4232 __ mov(r0, Operand(instr->arity()));
4219 __ mov(r2, Operand(instr->hydrogen()->property_cell())); 4233 __ mov(r2, Operand(instr->hydrogen()->property_cell()));
4220 Handle<Code> array_construct_code = 4234 Object* cell_value = instr->hydrogen()->property_cell()->value();
4221 isolate()->builtins()->ArrayConstructCode(); 4235 ElementsKind kind = static_cast<ElementsKind>(Smi::cast(cell_value)->value());
4222 4236 if (instr->arity() == 0) {
4223 CallCode(array_construct_code, RelocInfo::CONSTRUCT_CALL, instr); 4237 ArrayNoArgumentConstructorStub stub(kind);
4238 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4239 } else if (instr->arity() == 1) {
4240 ArraySingleArgumentConstructorStub stub(kind);
4241 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4242 } else {
4243 ArrayNArgumentsConstructorStub stub(kind);
4244 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4245 }
4224 } 4246 }
4225 4247
4226 4248
4227 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4249 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4228 CallRuntime(instr->function(), instr->arity(), instr); 4250 CallRuntime(instr->function(), instr->arity(), instr);
4229 } 4251 }
4230 4252
4231 4253
4232 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 4254 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4233 Register result = ToRegister(instr->result()); 4255 Register result = ToRegister(instr->result());
(...skipping 14 matching lines...) Expand all
4248 __ mov(scratch, Operand(instr->transition())); 4270 __ mov(scratch, Operand(instr->transition()));
4249 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 4271 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
4250 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 4272 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4251 Register temp = ToRegister(instr->temp()); 4273 Register temp = ToRegister(instr->temp());
4252 // Update the write barrier for the map field. 4274 // Update the write barrier for the map field.
4253 __ RecordWriteField(object, 4275 __ RecordWriteField(object,
4254 HeapObject::kMapOffset, 4276 HeapObject::kMapOffset,
4255 scratch, 4277 scratch,
4256 temp, 4278 temp,
4257 GetLinkRegisterState(), 4279 GetLinkRegisterState(),
4258 kSaveFPRegs, 4280 GetSaveFPRegsMode(),
4259 OMIT_REMEMBERED_SET, 4281 OMIT_REMEMBERED_SET,
4260 OMIT_SMI_CHECK); 4282 OMIT_SMI_CHECK);
4261 } 4283 }
4262 } 4284 }
4263 4285
4264 // Do the store. 4286 // Do the store.
4265 HType type = instr->hydrogen()->value()->type(); 4287 HType type = instr->hydrogen()->value()->type();
4266 SmiCheck check_needed = 4288 SmiCheck check_needed =
4267 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4289 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4268 if (instr->is_in_object()) { 4290 if (instr->is_in_object()) {
4269 __ str(value, FieldMemOperand(object, offset)); 4291 __ str(value, FieldMemOperand(object, offset));
4270 if (instr->hydrogen()->NeedsWriteBarrier()) { 4292 if (instr->hydrogen()->NeedsWriteBarrier()) {
4271 // Update the write barrier for the object for in-object properties. 4293 // Update the write barrier for the object for in-object properties.
4272 __ RecordWriteField(object, 4294 __ RecordWriteField(object,
4273 offset, 4295 offset,
4274 value, 4296 value,
4275 scratch, 4297 scratch,
4276 GetLinkRegisterState(), 4298 GetLinkRegisterState(),
4277 kSaveFPRegs, 4299 GetSaveFPRegsMode(),
4278 EMIT_REMEMBERED_SET, 4300 EMIT_REMEMBERED_SET,
4279 check_needed); 4301 check_needed);
4280 } 4302 }
4281 } else { 4303 } else {
4282 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); 4304 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
4283 __ str(value, FieldMemOperand(scratch, offset)); 4305 __ str(value, FieldMemOperand(scratch, offset));
4284 if (instr->hydrogen()->NeedsWriteBarrier()) { 4306 if (instr->hydrogen()->NeedsWriteBarrier()) {
4285 // Update the write barrier for the properties array. 4307 // Update the write barrier for the properties array.
4286 // object is used as a scratch register. 4308 // object is used as a scratch register.
4287 __ RecordWriteField(scratch, 4309 __ RecordWriteField(scratch,
4288 offset, 4310 offset,
4289 value, 4311 value,
4290 object, 4312 object,
4291 GetLinkRegisterState(), 4313 GetLinkRegisterState(),
4292 kSaveFPRegs, 4314 GetSaveFPRegsMode(),
4293 EMIT_REMEMBERED_SET, 4315 EMIT_REMEMBERED_SET,
4294 check_needed); 4316 check_needed);
4295 } 4317 }
4296 } 4318 }
4297 } 4319 }
4298 4320
4299 4321
4300 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 4322 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4301 ASSERT(ToRegister(instr->object()).is(r1)); 4323 ASSERT(ToRegister(instr->object()).is(r1));
4302 ASSERT(ToRegister(instr->value()).is(r0)); 4324 ASSERT(ToRegister(instr->value()).is(r0));
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
4477 if (instr->hydrogen()->NeedsWriteBarrier()) { 4499 if (instr->hydrogen()->NeedsWriteBarrier()) {
4478 HType type = instr->hydrogen()->value()->type(); 4500 HType type = instr->hydrogen()->value()->type();
4479 SmiCheck check_needed = 4501 SmiCheck check_needed =
4480 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4502 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4481 // Compute address of modified element and store it into key register. 4503 // Compute address of modified element and store it into key register.
4482 __ add(key, store_base, Operand(offset - kHeapObjectTag)); 4504 __ add(key, store_base, Operand(offset - kHeapObjectTag));
4483 __ RecordWrite(elements, 4505 __ RecordWrite(elements,
4484 key, 4506 key,
4485 value, 4507 value,
4486 GetLinkRegisterState(), 4508 GetLinkRegisterState(),
4487 kSaveFPRegs, 4509 GetSaveFPRegsMode(),
4488 EMIT_REMEMBERED_SET, 4510 EMIT_REMEMBERED_SET,
4489 check_needed); 4511 check_needed);
4490 } 4512 }
4491 } 4513 }
4492 4514
4493 4515
4494 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { 4516 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4495 // By cases: external, fast double 4517 // By cases: external, fast double
4496 if (instr->is_external()) { 4518 if (instr->is_external()) {
4497 DoStoreKeyedExternalArray(instr); 4519 DoStoreKeyedExternalArray(instr);
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after
5996 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 6018 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
5997 __ ldr(result, FieldMemOperand(scratch, 6019 __ ldr(result, FieldMemOperand(scratch,
5998 FixedArray::kHeaderSize - kPointerSize)); 6020 FixedArray::kHeaderSize - kPointerSize));
5999 __ bind(&done); 6021 __ bind(&done);
6000 } 6022 }
6001 6023
6002 6024
6003 #undef __ 6025 #undef __
6004 6026
6005 } } // namespace v8::internal 6027 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698