diff options
author | isaacs <i@izs.me> | 2012-02-23 16:35:46 -0800 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-02-27 12:11:09 -0800 |
commit | f4641bd4de566145e99b05c47c8f3d629b0223cd (patch) | |
tree | 2d0ccb1c338bec65881b30c49707d9e688fed154 /deps/v8/src/ia32/lithium-codegen-ia32.cc | |
parent | 82ad1f87fa99b420a97cc9bfae727fce0b1bf8a4 (diff) | |
download | node-f4641bd4de566145e99b05c47c8f3d629b0223cd.tar.gz |
Update v8 to 3.9.9
Diffstat (limited to 'deps/v8/src/ia32/lithium-codegen-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/lithium-codegen-ia32.cc | 165 |
1 files changed, 145 insertions, 20 deletions
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc index 5a276f452..fec330849 100644 --- a/deps/v8/src/ia32/lithium-codegen-ia32.cc +++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc @@ -1868,11 +1868,10 @@ void LCodeGen::EmitClassOfTest(Label* is_true, // Faster code path to avoid two compares: subtract lower bound from the // actual type and do a signed compare with the width of the type range. __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); - __ mov(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); + __ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); __ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); - __ cmpb(Operand(temp2), - static_cast<int8_t>(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - - FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); + __ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - + FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); __ j(above, is_false); } @@ -2690,6 +2689,15 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) { } +void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { + ASSERT(ToRegister(instr->InputAt(0)).is(esi)); + __ push(esi); // The context is the first argument. + __ push(Immediate(instr->hydrogen()->pairs())); + __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags()))); + CallRuntime(Runtime::kDeclareGlobals, 3, instr); +} + + void LCodeGen::DoGlobalObject(LGlobalObject* instr) { Register context = ToRegister(instr->context()); Register result = ToRegister(instr->result()); @@ -4070,7 +4078,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { } else { __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); __ and_(temp, mask); - __ cmpb(Operand(temp), tag); + __ cmp(temp, tag); DeoptimizeIf(not_equal, instr->environment()); } } @@ -4251,26 +4259,35 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, __ Assert(equal, "Unexpected object literal boilerplate"); } + // Only elements backing stores for non-COW arrays need to be copied. + Handle<FixedArrayBase> elements(object->elements()); + bool has_elements = elements->length() > 0 && + elements->map() != isolate()->heap()->fixed_cow_array_map(); + // Increase the offset so that subsequent objects end up right after - // this one. - int current_offset = *offset; - int size = object->map()->instance_size(); - *offset += size; + // this object and its backing store. + int object_offset = *offset; + int object_size = object->map()->instance_size(); + int elements_offset = *offset + object_size; + int elements_size = has_elements ? elements->Size() : 0; + *offset += object_size + elements_size; // Copy object header. ASSERT(object->properties()->length() == 0); - ASSERT(object->elements()->length() == 0 || - object->elements()->map() == isolate()->heap()->fixed_cow_array_map()); int inobject_properties = object->map()->inobject_properties(); - int header_size = size - inobject_properties * kPointerSize; + int header_size = object_size - inobject_properties * kPointerSize; for (int i = 0; i < header_size; i += kPointerSize) { - __ mov(ecx, FieldOperand(source, i)); - __ mov(FieldOperand(result, current_offset + i), ecx); + if (has_elements && i == JSObject::kElementsOffset) { + __ lea(ecx, Operand(result, elements_offset)); + } else { + __ mov(ecx, FieldOperand(source, i)); + } + __ mov(FieldOperand(result, object_offset + i), ecx); } // Copy in-object properties. for (int i = 0; i < inobject_properties; i++) { - int total_offset = current_offset + object->GetInObjectPropertyOffset(i); + int total_offset = object_offset + object->GetInObjectPropertyOffset(i); Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); if (value->IsJSObject()) { Handle<JSObject> value_object = Handle<JSObject>::cast(value); @@ -4285,10 +4302,40 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, __ mov(FieldOperand(result, total_offset), Immediate(value)); } } + + // Copy elements backing store header. + ASSERT(!has_elements || elements->IsFixedArray()); + if (has_elements) { + __ LoadHeapObject(source, elements); + for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { + __ mov(ecx, FieldOperand(source, i)); + __ mov(FieldOperand(result, elements_offset + i), ecx); + } + } + + // Copy elements backing store content. + ASSERT(!has_elements || elements->IsFixedArray()); + int elements_length = has_elements ? elements->length() : 0; + for (int i = 0; i < elements_length; i++) { + int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); + Handle<Object> value = JSObject::GetElement(object, i); + if (value->IsJSObject()) { + Handle<JSObject> value_object = Handle<JSObject>::cast(value); + __ lea(ecx, Operand(result, *offset)); + __ mov(FieldOperand(result, total_offset), ecx); + __ LoadHeapObject(source, value_object); + EmitDeepCopy(value_object, result, source, offset); + } else if (value->IsHeapObject()) { + __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value)); + __ mov(FieldOperand(result, total_offset), ecx); + } else { + __ mov(FieldOperand(result, total_offset), Immediate(value)); + } + } } -void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) { +void LCodeGen::DoFastLiteral(LFastLiteral* instr) { ASSERT(ToRegister(instr->context()).is(esi)); int size = instr->hydrogen()->total_size(); @@ -4310,14 +4357,14 @@ void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) { } -void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) { +void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { ASSERT(ToRegister(instr->context()).is(esi)); + Handle<FixedArray> literals(instr->environment()->closure()->literals()); Handle<FixedArray> constant_properties = instr->hydrogen()->constant_properties(); // Set up the parameters to the stub/runtime call. - __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); - __ push(FieldOperand(eax, JSFunction::kLiteralsOffset)); + __ PushHeapObject(literals); __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); __ push(Immediate(constant_properties)); int flags = instr->hydrogen()->fast_elements() @@ -4414,7 +4461,7 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { __ push(Immediate(shared_info)); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } else { - __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); + __ push(esi); __ push(Immediate(shared_info)); __ push(Immediate(pretenure ? factory()->true_value() @@ -4682,6 +4729,84 @@ void LCodeGen::DoIn(LIn* instr) { } +void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { + __ cmp(eax, isolate()->factory()->undefined_value()); + DeoptimizeIf(equal, instr->environment()); + + __ cmp(eax, isolate()->factory()->null_value()); + DeoptimizeIf(equal, instr->environment()); + + __ test(eax, Immediate(kSmiTagMask)); + DeoptimizeIf(zero, instr->environment()); + + STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); + __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); + DeoptimizeIf(below_equal, instr->environment()); + + Label use_cache, call_runtime; + __ CheckEnumCache(&call_runtime); + + __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); + __ jmp(&use_cache, Label::kNear); + + // Get the set of properties to enumerate. + __ bind(&call_runtime); + __ push(eax); + CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); + + __ cmp(FieldOperand(eax, HeapObject::kMapOffset), + isolate()->factory()->meta_map()); + DeoptimizeIf(not_equal, instr->environment()); + __ bind(&use_cache); +} + + +void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { + Register map = ToRegister(instr->map()); + Register result = ToRegister(instr->result()); + __ LoadInstanceDescriptors(map, result); + __ mov(result, + FieldOperand(result, DescriptorArray::kEnumerationIndexOffset)); + __ mov(result, + FieldOperand(result, FixedArray::SizeFor(instr->idx()))); + __ test(result, result); + DeoptimizeIf(equal, instr->environment()); +} + + +void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { + Register object = ToRegister(instr->value()); + __ cmp(ToRegister(instr->map()), + FieldOperand(object, HeapObject::kMapOffset)); + DeoptimizeIf(not_equal, instr->environment()); +} + + +void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { + Register object = ToRegister(instr->object()); + Register index = ToRegister(instr->index()); + + Label out_of_object, done; + __ cmp(index, Immediate(0)); + __ j(less, &out_of_object); + __ mov(object, FieldOperand(object, + index, + times_half_pointer_size, + JSObject::kHeaderSize)); + __ jmp(&done, Label::kNear); + + __ bind(&out_of_object); + __ mov(object, FieldOperand(object, JSObject::kPropertiesOffset)); + __ neg(index); + // Index is now equal to out of object property index plus 1. + __ mov(object, FieldOperand(object, + index, + times_half_pointer_size, + FixedArray::kHeaderSize - kPointerSize)); + __ bind(&done); +} + + #undef __ } } // namespace v8::internal |