Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1898 __ mov(r0, Operand(Factory::true_value()), LeaveCC, eq); | 1898 __ mov(r0, Operand(Factory::true_value()), LeaveCC, eq); |
| 1899 } | 1899 } |
| 1900 | 1900 |
| 1901 | 1901 |
| 1902 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { | 1902 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { |
| 1903 Abort("DoInstanceOfAndBranch unimplemented."); | 1903 Abort("DoInstanceOfAndBranch unimplemented."); |
| 1904 } | 1904 } |
| 1905 | 1905 |
| 1906 | 1906 |
| 1907 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 1907 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { |
| 1908 Abort("DoInstanceOfKnownGlobal unimplemented."); | 1908 class DeferredInstanceOfKnownGlobal: public LDeferredCode { |
| 1909 public: | |
| 1910 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, | |
| 1911 LInstanceOfKnownGlobal* instr) | |
| 1912 : LDeferredCode(codegen), instr_(instr) { } | |
| 1913 virtual void Generate() { | |
| 1914 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); | |
| 1915 } | |
| 1916 | |
| 1917 Label* map_check() { return &map_check_; } | |
| 1918 | |
| 1919 private: | |
| 1920 LInstanceOfKnownGlobal* instr_; | |
| 1921 Label map_check_; | |
| 1922 }; | |
| 1923 | |
| 1924 DeferredInstanceOfKnownGlobal* deferred; | |
| 1925 deferred = new DeferredInstanceOfKnownGlobal(this, instr); | |
| 1926 | |
| 1927 Label done, false_result; | |
| 1928 Register object = ToRegister(instr->input()); | |
| 1929 Register temp = ToRegister(instr->temp()); | |
| 1930 Register result = ToRegister(instr->result()); | |
| 1931 | |
| 1932 ASSERT(object.is(r0)); | |
| 1933 ASSERT(result.is(r0)); | |
| 1934 | |
| 1935 // A Smi is not instance of anything. | |
| 1936 __ BranchOnSmi(object, &false_result); | |
| 1937 | |
| 1938 // This is the inlined call site instanceof cache. The two occurences of the | |
| 1939 // hole value will be patched to the last map/result pair generated by the | |
| 1940 // instanceof stub. | |
| 1941 Label cache_miss; | |
| 1942 Register map = temp; | |
| 1943 __ ldr(map, FieldMemOperand(object, HeapObject::kMapOffset)); | |
| 1944 __ bind(deferred->map_check()); // Label for calculating code patching. | |
| 1945 // We use Factory::the_hole_value() on purpose instead of loading from the | |
| 1946 // root array to force relocation to be able to later patch with | |
| 1947 // the cached map. | |
| 1948 __ mov(ip, Operand(Factory::the_hole_value())); | |
| 1949 __ cmp(map, Operand(ip)); | |
| 1950 __ b(ne, &cache_miss); | |
| 1951 // We use Factory::the_hole_value() on purpose instead of loading from the | |
| 1952 // root array to force relocation to be able to later patch | |
| 1953 // with true or false. | |
| 1954 __ mov(result, Operand(Factory::the_hole_value())); | |
| 1955 __ b(&done); | |
| 1956 | |
| 1957 // The inlined call site cache did not match. Check null and string before | |
| 1958 // calling the deferred code. | |
| 1959 __ bind(&cache_miss); | |
| 1960 // Null is not instance of anything. | |
| 1961 __ LoadRoot(ip, Heap::kNullValueRootIndex); | |
| 1962 __ cmp(object, Operand(ip)); | |
| 1963 __ b(eq, &false_result); | |
| 1964 | |
| 1965 // String values is not instance of anything. | |
| 1966 Condition is_string = masm_->IsObjectStringType(object, temp); | |
| 1967 __ b(is_string, &false_result); | |
| 1968 | |
| 1969 // Go to the deferred code. | |
| 1970 __ b(deferred->entry()); | |
| 1971 | |
| 1972 __ bind(&false_result); | |
| 1973 __ LoadRoot(result, Heap::kFalseValueRootIndex); | |
| 1974 | |
| 1975 // Here result has either true or false. Deferred code also produces true or | |
| 1976 // false object. | |
| 1977 __ bind(deferred->exit()); | |
| 1978 __ bind(&done); | |
| 1979 } | |
| 1980 | |
| 1981 | |
| 1982 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, | |
| 1983 Label* map_check) { | |
| 1984 Register result = ToRegister(instr->result()); | |
| 1985 | |
| 1986 InstanceofStub::Flags flags = InstanceofStub::kNoFlags; | |
| 1987 flags = static_cast<InstanceofStub::Flags>( | |
| 1988 flags | InstanceofStub::kArgsInRegisters); | |
| 1989 flags = static_cast<InstanceofStub::Flags>( | |
| 1990 flags | InstanceofStub::kCallSiteInlineCheck); | |
| 1991 flags = static_cast<InstanceofStub::Flags>( | |
| 1992 flags | InstanceofStub::kReturnTrueFalseObject); | |
| 1993 InstanceofStub stub(flags); | |
| 1994 | |
| 1995 __ PushSafepointRegisters(); | |
|
Søren Thygesen Gjesse
2011/01/17 13:18:07
I think we need to use PushSafepointRegistersAndDo
Alexandre
2011/01/17 18:06:41
Do we really need to? The InstanceofStub doesn't u
| |
| 1996 | |
| 1997 // Get the temp register reserved by the instruction. This needs to be r4 as | |
| 1998 // its slot of the pushing of safepoint registers is used to communicate the | |
| 1999 // offset to the location of the map check. | |
| 2000 Register temp = ToRegister(instr->temp()); | |
| 2001 ASSERT(temp.is(r4)); | |
| 2002 __ mov(InstanceofStub::right(), Operand(instr->function())); | |
| 2003 static const int kAdditionalDelta = 4; | |
| 2004 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; | |
| 2005 Label before_push_delta; | |
| 2006 __ bind(&before_push_delta); | |
| 2007 __ BlockConstPoolFor(4); | |
|
Søren Thygesen Gjesse
2011/01/17 13:18:07
4 -> kAdditionalDelta
Alexandre
2011/01/17 18:06:41
Done.
| |
| 2008 __ mov(temp, Operand(delta * kPointerSize)); | |
| 2009 __ StoreToSafepointRegisters(temp); | |
| 2010 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | |
| 2011 ASSERT_EQ(kAdditionalDelta, | |
| 2012 masm_->InstructionsGeneratedSince(&before_push_delta)); | |
| 2013 RecordSafepointWithRegisters( | |
|
Søren Thygesen Gjesse
2011/01/17 13:18:07
Use RecordSafepointWithRegistersAndDoubles here.
Alexandre
2011/01/17 18:06:41
See previous comment about PushSafepointRegisters.
| |
| 2014 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); | |
| 2015 // Put the result value into the result register slot and | |
| 2016 // restore all registers. | |
| 2017 __ str(r0, MemOperand(sp, result.code() * kPointerSize)); | |
|
Søren Thygesen Gjesse
2011/01/17 13:18:07
Use StoreToSafepointRegisterSlot here.
Alexandre
2011/01/17 18:06:41
Done.
Added an ASSERT to check that instr->result(
| |
| 2018 | |
| 2019 __ PopSafepointRegisters(); | |
|
Søren Thygesen Gjesse
2011/01/17 13:18:07
And use PopSafepointRegistersAndDoubles here.
Alexandre
2011/01/17 18:06:41
See previous comment about PushSafepointRegisters.
| |
| 1909 } | 2020 } |
| 1910 | 2021 |
| 1911 | 2022 |
| 1912 static Condition ComputeCompareCondition(Token::Value op) { | 2023 static Condition ComputeCompareCondition(Token::Value op) { |
| 1913 switch (op) { | 2024 switch (op) { |
| 1914 case Token::EQ_STRICT: | 2025 case Token::EQ_STRICT: |
| 1915 case Token::EQ: | 2026 case Token::EQ: |
| 1916 return eq; | 2027 return eq; |
| 1917 case Token::LT: | 2028 case Token::LT: |
| 1918 return lt; | 2029 return lt; |
| (...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3179 | 3290 |
| 3180 | 3291 |
| 3181 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 3292 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
| 3182 Abort("DoOsrEntry unimplemented."); | 3293 Abort("DoOsrEntry unimplemented."); |
| 3183 } | 3294 } |
| 3184 | 3295 |
| 3185 | 3296 |
| 3186 #undef __ | 3297 #undef __ |
| 3187 | 3298 |
| 3188 } } // namespace v8::internal | 3299 } } // namespace v8::internal |
| OLD | NEW |