Commit 4732c219 authored by klaasb's avatar klaasb Committed by Commit bot

[interpreter] Remove redundant code in ForInPrepare

ForInPrepare checked whether the receiver object was null, undefined or
converted to a JSObject. This is already done by the generated bytecode.

BUG=v8:4820
LOG=n

Review-Url: https://codereview.chromium.org/2208043002
Cr-Commit-Position: refs/heads/master@{#38394}
parent 3651bff0
...@@ -66,6 +66,7 @@ namespace internal { ...@@ -66,6 +66,7 @@ namespace internal {
V(kExpectedBooleanValue, "Expected boolean value") \ V(kExpectedBooleanValue, "Expected boolean value") \
V(kExpectedFunctionObject, "Expected function object in register") \ V(kExpectedFunctionObject, "Expected function object in register") \
V(kExpectedHeapNumber, "Expected HeapNumber") \ V(kExpectedHeapNumber, "Expected HeapNumber") \
V(kExpectedJSReceiver, "Expected object to have receiver type") \
V(kExpectedNativeContext, "Expected native context") \ V(kExpectedNativeContext, "Expected native context") \
V(kExpectedNonIdenticalObjects, "Expected non-identical objects") \ V(kExpectedNonIdenticalObjects, "Expected non-identical objects") \
V(kExpectedNonNullContext, "Expected non-null context") \ V(kExpectedNonNullContext, "Expected non-null context") \
......
...@@ -1902,67 +1902,45 @@ void Interpreter::BuildForInPrepareResult(Node* output_register, ...@@ -1902,67 +1902,45 @@ void Interpreter::BuildForInPrepareResult(Node* output_register,
__ StoreRegister(cache_length, output_register); __ StoreRegister(cache_length, output_register);
} }
// ForInPrepare <cache_info_triple> // ForInPrepare <receiver> <cache_info_triple>
// //
// Returns state for for..in loop execution based on the object in the // Returns state for for..in loop execution based on the object in the register
// accumulator. The result is output in registers |cache_info_triple| to // |receiver|. The object must not be null or undefined and must have been
// converted to a receiver already.
// The result is output in registers |cache_info_triple| to
// |cache_info_triple + 2|, with the registers holding cache_type, cache_array, // |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
// and cache_length respectively. // and cache_length respectively.
void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) { void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
Node* object_reg = __ BytecodeOperandReg(0); Node* object_reg = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(object_reg); Node* receiver = __ LoadRegister(object_reg);
Node* context = __ GetContext(); Node* context = __ GetContext();
Node* const zero_smi = __ SmiConstant(Smi::FromInt(0)); Node* const zero_smi = __ SmiConstant(Smi::FromInt(0));
Label test_if_null(assembler), test_if_undefined(assembler), Label nothing_to_iterate(assembler, Label::kDeferred),
nothing_to_iterate(assembler, Label::kDeferred), use_enum_cache(assembler), use_runtime(assembler, Label::kDeferred);
convert_to_receiver(assembler, Label::kDeferred),
already_receiver(assembler), check_enum_cache(assembler);
Variable receiver(assembler, MachineRepresentation::kTagged); if (FLAG_debug_code) {
Label already_receiver(assembler), abort(assembler);
// Test if object is already a receiver, no conversion necessary if so. Node* instance_type = __ LoadInstanceType(receiver);
Node* instance_type = __ LoadInstanceType(object); Node* first_receiver_type = __ Int32Constant(FIRST_JS_RECEIVER_TYPE);
Node* first_receiver_type = __ Int32Constant(FIRST_JS_RECEIVER_TYPE); __ BranchIfInt32GreaterThanOrEqual(instance_type, first_receiver_type,
__ BranchIfInt32GreaterThanOrEqual(instance_type, first_receiver_type, &already_receiver, &abort);
&already_receiver, &test_if_null); __ Bind(&abort);
{
__ Bind(&test_if_null); __ Abort(kExpectedJSReceiver);
{ // TODO(klaasb) remove this unreachable Goto once Abort ends the block
__ BranchIfWordEqual(object, assembler->NullConstant(), &nothing_to_iterate, __ Goto(&already_receiver);
&test_if_undefined); }
} __ Bind(&already_receiver);
__ Bind(&test_if_undefined);
{
__ BranchIfWordEqual(object, assembler->UndefinedConstant(),
&nothing_to_iterate, &convert_to_receiver);
}
__ Bind(&convert_to_receiver);
{
Callable callable = CodeFactory::ToObject(assembler->isolate());
Node* target = __ HeapConstant(callable.code());
Node* result = __ CallStub(callable.descriptor(), target, context, object);
receiver.Bind(result);
__ Goto(&check_enum_cache);
}
__ Bind(&already_receiver);
{
receiver.Bind(object);
__ Goto(&check_enum_cache);
} }
Label use_enum_cache(assembler), use_runtime(assembler, Label::kDeferred); __ CheckEnumCache(receiver, &use_enum_cache, &use_runtime);
__ Bind(&check_enum_cache);
{ __ CheckEnumCache(receiver.value(), &use_enum_cache, &use_runtime); }
__ Bind(&use_enum_cache); __ Bind(&use_enum_cache);
{ {
// The enum cache is valid. Load the map of the object being // The enum cache is valid. Load the map of the object being
// iterated over and use the cache for the iteration. // iterated over and use the cache for the iteration.
Node* cache_type = __ LoadMap(receiver.value()); Node* cache_type = __ LoadMap(receiver);
Node* cache_length = __ EnumLength(cache_type); Node* cache_length = __ EnumLength(cache_type);
__ GotoIf(assembler->WordEqual(cache_length, zero_smi), __ GotoIf(assembler->WordEqual(cache_length, zero_smi),
&nothing_to_iterate); &nothing_to_iterate);
...@@ -1980,7 +1958,7 @@ void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) { ...@@ -1980,7 +1958,7 @@ void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
__ Bind(&use_runtime); __ Bind(&use_runtime);
{ {
Node* result_triple = Node* result_triple =
__ CallRuntime(Runtime::kForInPrepare, context, object); __ CallRuntime(Runtime::kForInPrepare, context, receiver);
Node* cache_type = __ Projection(0, result_triple); Node* cache_type = __ Projection(0, result_triple);
Node* cache_array = __ Projection(1, result_triple); Node* cache_array = __ Projection(1, result_triple);
Node* cache_length = __ Projection(2, result_triple); Node* cache_length = __ Projection(2, result_triple);
......
...@@ -24,7 +24,7 @@ bytecodes: [ ...@@ -24,7 +24,7 @@ bytecodes: [
B(LdaZero), B(LdaZero),
B(TestEqualStrict), R(1), B(TestEqualStrict), R(1),
B(JumpIfTrue), U8(53), B(JumpIfTrue), U8(53),
B(LdaSmi), U8(75), B(LdaSmi), U8(76),
B(Star), R(2), B(Star), R(2),
B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1), B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
B(CreateFunctionContext), U8(2), B(CreateFunctionContext), U8(2),
...@@ -130,7 +130,7 @@ bytecodes: [ ...@@ -130,7 +130,7 @@ bytecodes: [
B(LdaSmi), U8(1), B(LdaSmi), U8(1),
B(TestEqualStrict), R(1), B(TestEqualStrict), R(1),
B(JumpIfTrueConstant), U8(0), B(JumpIfTrueConstant), U8(0),
B(LdaSmi), U8(75), B(LdaSmi), U8(76),
B(Star), R(2), B(Star), R(2),
B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1), B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
B(CreateFunctionContext), U8(2), B(CreateFunctionContext), U8(2),
...@@ -276,7 +276,7 @@ bytecodes: [ ...@@ -276,7 +276,7 @@ bytecodes: [
B(LdaSmi), U8(1), B(LdaSmi), U8(1),
B(TestEqualStrict), R(4), B(TestEqualStrict), R(4),
B(JumpIfTrueConstant), U8(3), B(JumpIfTrueConstant), U8(3),
B(LdaSmi), U8(75), B(LdaSmi), U8(76),
B(Star), R(5), B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1), B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
B(CreateFunctionContext), U8(9), B(CreateFunctionContext), U8(9),
...@@ -342,7 +342,7 @@ bytecodes: [ ...@@ -342,7 +342,7 @@ bytecodes: [
B(LdaSmi), U8(1), B(LdaSmi), U8(1),
B(TestEqualStrict), R(4), B(TestEqualStrict), R(4),
B(JumpIfTrueConstant), U8(9), B(JumpIfTrueConstant), U8(9),
B(LdaSmi), U8(75), B(LdaSmi), U8(76),
B(Star), R(12), B(Star), R(12),
B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1), B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
/* 27 S> */ B(LdrContextSlot), R(1), U8(7), R(14), /* 27 S> */ B(LdrContextSlot), R(1), U8(7), R(14),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment