| Index: src/arm/lithium-codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/lithium-codegen-arm.cc (revision 10404)
|
| +++ src/arm/lithium-codegen-arm.cc (working copy)
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2011 the V8 project authors. All rights reserved.
|
| +// Copyright 2012 the V8 project authors. All rights reserved.
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| // met:
|
| @@ -1994,7 +1994,7 @@
|
|
|
|
|
| // Branches to a label or falls through with the answer in flags. Trashes
|
| -// the temp registers, but not the input. Only input and temp2 may alias.
|
| +// the temp registers, but not the input.
|
| void LCodeGen::EmitClassOfTest(Label* is_true,
|
| Label* is_false,
|
| Handle<String>class_name,
|
| @@ -2002,7 +2002,9 @@
|
| Register temp,
|
| Register temp2) {
|
| ASSERT(!input.is(temp));
|
| - ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register.
|
| + ASSERT(!input.is(temp2));
|
| + ASSERT(!temp.is(temp2));
|
| +
|
| __ JumpIfSmi(input, is_false);
|
|
|
| if (class_name->IsEqualTo(CStrVector("Function"))) {
|
| @@ -2141,7 +2143,10 @@
|
| // We use Factory::the_hole_value() on purpose instead of loading from the
|
| // root array to force relocation to be able to later patch with
|
| // the cached map.
|
| - __ mov(ip, Operand(factory()->the_hole_value()));
|
| + Handle<JSGlobalPropertyCell> cell =
|
| + factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
|
| + __ mov(ip, Operand(Handle<Object>(cell)));
|
| + __ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
|
| __ cmp(map, Operand(ip));
|
| __ b(ne, &cache_miss);
|
| // We use Factory::the_hole_value() on purpose instead of loading from the
|
| @@ -2901,7 +2906,7 @@
|
| __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
|
| __ Call(ip);
|
|
|
| - // Setup deoptimization.
|
| + // Set up deoptimization.
|
| RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
|
|
|
| // Restore context.
|
| @@ -3190,6 +3195,30 @@
|
| }
|
|
|
|
|
| +void LCodeGen::DoRandom(LRandom* instr) {
|
| + // Having marked this instruction as a call we can use any
|
| + // registers.
|
| + ASSERT(ToDoubleRegister(instr->result()).is(d7));
|
| + ASSERT(ToRegister(instr->InputAt(0)).is(r0));
|
| +
|
| + __ PrepareCallCFunction(1, scratch0());
|
| + __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset));
|
| + __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
|
| +
|
| + // 0x41300000 is the top half of 1.0 x 2^20 as a double.
|
| + // Create this constant using mov/orr to avoid PC relative load.
|
| + __ mov(r1, Operand(0x41000000));
|
| + __ orr(r1, r1, Operand(0x300000));
|
| + // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
|
| + __ vmov(d7, r0, r1);
|
| + // Move 0x4130000000000000 to VFP.
|
| + __ mov(r0, Operand(0, RelocInfo::NONE));
|
| + __ vmov(d8, r0, r1);
|
| + // Subtract and store the result in the heap number.
|
| + __ vsub(d7, d7, d8);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
|
| ASSERT(ToDoubleRegister(instr->result()).is(d2));
|
| TranscendentalCacheStub stub(TranscendentalCache::LOG,
|
| @@ -3874,6 +3903,7 @@
|
| void LCodeGen::EmitNumberUntagD(Register input_reg,
|
| DoubleRegister result_reg,
|
| bool deoptimize_on_undefined,
|
| + bool deoptimize_on_minus_zero,
|
| LEnvironment* env) {
|
| Register scratch = scratch0();
|
| SwVfpRegister flt_scratch = double_scratch0().low();
|
| @@ -3909,6 +3939,14 @@
|
| // Heap number to double register conversion.
|
| __ sub(ip, input_reg, Operand(kHeapObjectTag));
|
| __ vldr(result_reg, ip, HeapNumber::kValueOffset);
|
| + if (deoptimize_on_minus_zero) {
|
| + __ vmov(ip, result_reg.low());
|
| + __ cmp(ip, Operand(0));
|
| + __ b(ne, &done);
|
| + __ vmov(ip, result_reg.high());
|
| + __ cmp(ip, Operand(HeapNumber::kSignMask));
|
| + DeoptimizeIf(eq, env);
|
| + }
|
| __ jmp(&done);
|
|
|
| // Smi to double register conversion
|
| @@ -4042,6 +4080,7 @@
|
|
|
| EmitNumberUntagD(input_reg, result_reg,
|
| instr->hydrogen()->deoptimize_on_undefined(),
|
| + instr->hydrogen()->deoptimize_on_minus_zero(),
|
| instr->environment());
|
| }
|
|
|
| @@ -4155,14 +4194,26 @@
|
| }
|
|
|
|
|
| +void LCodeGen::DoCheckMapCommon(Register reg,
|
| + Register scratch,
|
| + Handle<Map> map,
|
| + CompareMapMode mode,
|
| + LEnvironment* env) {
|
| + Label success;
|
| + __ CompareMap(reg, scratch, map, &success, mode);
|
| + DeoptimizeIf(ne, env);
|
| + __ bind(&success);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoCheckMap(LCheckMap* instr) {
|
| Register scratch = scratch0();
|
| LOperand* input = instr->InputAt(0);
|
| ASSERT(input->IsRegister());
|
| Register reg = ToRegister(input);
|
| - __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
|
| - __ cmp(scratch, Operand(instr->hydrogen()->map()));
|
| - DeoptimizeIf(ne, instr->environment());
|
| + Handle<Map> map = instr->hydrogen()->map();
|
| + DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(),
|
| + instr->environment());
|
| }
|
|
|
|
|
| @@ -4231,9 +4282,9 @@
|
|
|
| // Check prototype maps up to the holder.
|
| while (!current_prototype.is_identical_to(holder)) {
|
| - __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
|
| - __ cmp(temp2, Operand(Handle<Map>(current_prototype->map())));
|
| - DeoptimizeIf(ne, instr->environment());
|
| + DoCheckMapCommon(temp1, temp2,
|
| + Handle<Map>(current_prototype->map()),
|
| + ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
|
| current_prototype =
|
| Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
|
| // Load next prototype object.
|
| @@ -4241,8 +4292,9 @@
|
| }
|
|
|
| // Check the holder map.
|
| - __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
|
| - __ cmp(temp2, Operand(Handle<Map>(current_prototype->map())));
|
| + DoCheckMapCommon(temp1, temp2,
|
| + Handle<Map>(current_prototype->map()),
|
| + ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
|
| DeoptimizeIf(ne, instr->environment());
|
| }
|
|
|
|
|