Chromium Code Reviews| 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 |