OLD | NEW |
---|---|
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1864 Result temp = left_side; | 1864 Result temp = left_side; |
1865 left_side = right_side; | 1865 left_side = right_side; |
1866 right_side = temp; | 1866 right_side = temp; |
1867 cc = ReverseCondition(cc); | 1867 cc = ReverseCondition(cc); |
1868 // This may reintroduce greater or less_equal as the value of cc. | 1868 // This may reintroduce greater or less_equal as the value of cc. |
1869 // CompareStub and the inline code both support all values of cc. | 1869 // CompareStub and the inline code both support all values of cc. |
1870 } | 1870 } |
1871 // Implement comparison against a constant Smi, inlining the case | 1871 // Implement comparison against a constant Smi, inlining the case |
1872 // where both sides are Smis. | 1872 // where both sides are Smis. |
1873 left_side.ToRegister(); | 1873 left_side.ToRegister(); |
1874 ASSERT(left_side.is_valid()); | 1874 |
1875 // Here we split control flow to the stub call and inlined cases | |
1876 // before finally splitting it to the control destination. We use | |
1877 // a jump target and branching to duplicate the virtual frame at | |
1878 // the first split. We manually handle the off-frame references | |
1879 // by reconstituting them on the non-fall-through path. | |
1875 JumpTarget is_smi; | 1880 JumpTarget is_smi; |
1881 Register left_reg = left_side.reg(); | |
1882 Handle<Object> right_val = right_side.handle(); | |
1876 __ test(left_side.reg(), Immediate(kSmiTagMask)); | 1883 __ test(left_side.reg(), Immediate(kSmiTagMask)); |
1877 is_smi.Branch(zero, &left_side, &right_side, taken); | 1884 is_smi.Branch(zero, taken); |
1878 | 1885 |
1879 // Setup and call the compare stub, which expects its arguments | 1886 // Setup and call the compare stub. |
1880 // in registers. | |
1881 CompareStub stub(cc, strict); | 1887 CompareStub stub(cc, strict); |
1882 Result result = frame_->CallStub(&stub, &left_side, &right_side); | 1888 Result result = frame_->CallStub(&stub, &left_side, &right_side); |
1883 result.ToRegister(); | 1889 result.ToRegister(); |
1884 __ cmp(result.reg(), 0); | 1890 __ cmp(result.reg(), 0); |
1885 result.Unuse(); | 1891 result.Unuse(); |
1886 dest->true_target()->Branch(cc); | 1892 dest->true_target()->Branch(cc); |
1887 dest->false_target()->Jump(); | 1893 dest->false_target()->Jump(); |
1888 | 1894 |
1889 is_smi.Bind(&left_side, &right_side); | 1895 is_smi.Bind(); |
1890 left_side.ToRegister(); | 1896 left_side = Result(left_reg); |
1897 right_side = Result(right_val); | |
1891 // Test smi equality and comparison by signed int comparison. | 1898 // Test smi equality and comparison by signed int comparison. |
1892 if (IsUnsafeSmi(right_side.handle())) { | 1899 if (IsUnsafeSmi(right_side.handle())) { |
1893 right_side.ToRegister(); | 1900 right_side.ToRegister(); |
1894 ASSERT(right_side.is_valid()); | |
1895 __ cmp(left_side.reg(), Operand(right_side.reg())); | 1901 __ cmp(left_side.reg(), Operand(right_side.reg())); |
1896 } else { | 1902 } else { |
1897 __ cmp(Operand(left_side.reg()), Immediate(right_side.handle())); | 1903 __ cmp(Operand(left_side.reg()), Immediate(right_side.handle())); |
1898 } | 1904 } |
1899 left_side.Unuse(); | 1905 left_side.Unuse(); |
1900 right_side.Unuse(); | 1906 right_side.Unuse(); |
1901 dest->Split(cc); | 1907 dest->Split(cc); |
1902 } | 1908 } |
1903 } else if (cc == equal && | 1909 } else if (cc == equal && |
1904 (left_side_constant_null || right_side_constant_null)) { | 1910 (left_side_constant_null || right_side_constant_null)) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1936 operand.Unuse(); | 1942 operand.Unuse(); |
1937 dest->Split(not_zero); | 1943 dest->Split(not_zero); |
1938 } | 1944 } |
1939 } else { // Neither side is a constant Smi or null. | 1945 } else { // Neither side is a constant Smi or null. |
1940 // If either side is a non-smi constant, skip the smi check. | 1946 // If either side is a non-smi constant, skip the smi check. |
1941 bool known_non_smi = | 1947 bool known_non_smi = |
1942 (left_side.is_constant() && !left_side.handle()->IsSmi()) || | 1948 (left_side.is_constant() && !left_side.handle()->IsSmi()) || |
1943 (right_side.is_constant() && !right_side.handle()->IsSmi()); | 1949 (right_side.is_constant() && !right_side.handle()->IsSmi()); |
1944 left_side.ToRegister(); | 1950 left_side.ToRegister(); |
1945 right_side.ToRegister(); | 1951 right_side.ToRegister(); |
1946 JumpTarget is_smi; | 1952 |
1947 if (!known_non_smi) { | 1953 if (known_non_smi) { |
1948 // Check for the smi case. | 1954 // When non-smi, call out to the compare stub. |
1955 CompareStub stub(cc, strict); | |
1956 Result answer = frame_->CallStub(&stub, &left_side, &right_side); | |
1957 if (cc == equal) { | |
1958 __ test(answer.reg(), Operand(answer.reg())); | |
1959 } else { | |
1960 __ cmp(answer.reg(), 0); | |
1961 } | |
1962 answer.Unuse(); | |
1963 dest->Split(cc); | |
1964 } else { | |
1965 // Here we split control flow to the stub call and inlined cases | |
1966 // before finally splitting it to the control destination. We use | |
1967 // a jump target and branching to duplicate the virtual frame at | |
1968 // the first split. We manually handle the off-frame references | |
1969 // by reconstituting them on the non-fall-through path. | |
1970 JumpTarget is_smi; | |
1971 Register left_reg = left_side.reg(); | |
1972 Register right_reg = right_side.reg(); | |
1973 | |
1949 Result temp = allocator_->Allocate(); | 1974 Result temp = allocator_->Allocate(); |
1950 ASSERT(temp.is_valid()); | 1975 ASSERT(temp.is_valid()); |
1951 __ mov(temp.reg(), left_side.reg()); | 1976 __ mov(temp.reg(), left_side.reg()); |
1952 __ or_(temp.reg(), Operand(right_side.reg())); | 1977 __ or_(temp.reg(), Operand(right_side.reg())); |
1953 __ test(temp.reg(), Immediate(kSmiTagMask)); | 1978 __ test(temp.reg(), Immediate(kSmiTagMask)); |
1954 temp.Unuse(); | 1979 temp.Unuse(); |
1955 is_smi.Branch(zero, &left_side, &right_side, taken); | 1980 is_smi.Branch(zero, taken); |
1956 } | 1981 // When non-smi, call out to the compare stub. |
1957 // When non-smi, call out to the compare stub, which expects its | 1982 CompareStub stub(cc, strict); |
1958 // arguments in registers. | 1983 Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
William Hesse
2009/06/12 14:05:38
Is it worth a comment that here is where left_side
| |
1959 CompareStub stub(cc, strict); | 1984 if (cc == equal) { |
1960 Result answer = frame_->CallStub(&stub, &left_side, &right_side); | 1985 __ test(answer.reg(), Operand(answer.reg())); |
1961 if (cc == equal) { | 1986 } else { |
1962 __ test(answer.reg(), Operand(answer.reg())); | 1987 __ cmp(answer.reg(), 0); |
1963 } else { | 1988 } |
1964 __ cmp(answer.reg(), 0); | 1989 answer.Unuse(); |
1965 } | |
1966 answer.Unuse(); | |
1967 if (known_non_smi) { | |
1968 dest->Split(cc); | |
1969 } else { | |
1970 dest->true_target()->Branch(cc); | 1990 dest->true_target()->Branch(cc); |
1971 dest->false_target()->Jump(); | 1991 dest->false_target()->Jump(); |
1972 is_smi.Bind(&left_side, &right_side); | 1992 |
1973 left_side.ToRegister(); | 1993 is_smi.Bind(); |
1974 right_side.ToRegister(); | 1994 left_side = Result(left_reg); |
1995 right_side = Result(right_reg); | |
1975 __ cmp(left_side.reg(), Operand(right_side.reg())); | 1996 __ cmp(left_side.reg(), Operand(right_side.reg())); |
1976 right_side.Unuse(); | 1997 right_side.Unuse(); |
1977 left_side.Unuse(); | 1998 left_side.Unuse(); |
1978 dest->Split(cc); | 1999 dest->Split(cc); |
1979 } | 2000 } |
1980 } | 2001 } |
1981 } | 2002 } |
1982 | 2003 |
1983 | 2004 |
1984 class CallFunctionStub: public CodeStub { | 2005 class CallFunctionStub: public CodeStub { |
(...skipping 5486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7471 | 7492 |
7472 // Slow-case: Go through the JavaScript implementation. | 7493 // Slow-case: Go through the JavaScript implementation. |
7473 __ bind(&slow); | 7494 __ bind(&slow); |
7474 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 7495 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
7475 } | 7496 } |
7476 | 7497 |
7477 | 7498 |
7478 #undef __ | 7499 #undef __ |
7479 | 7500 |
7480 } } // namespace v8::internal | 7501 } } // namespace v8::internal |
OLD | NEW |