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 |