Skip to content

Commit 351126a

Browse files
edwinsmithfacebook-github-bot
authored andcommitted
split isame() into tsame() + fsame()
Summary: Let's take a divide & conquer approach to fixing dynamic case collisions by separating function and type name collisions. Unfortunately, throughout HHVM we have hardcoded how names of each kind should be compared by explicitly calling isame(), istrcmp(), etc. A better design would have been to wrap names in zero-overhead newtype structs so their operations could be implemented in one place, and C++ type safety could help us properly juggle multiple name types. Anyway, this takes a first step; I cloned isame() and istrcmp() into t/fsame() and t/fstrcmp(), then propagated the split through the codebase. This gives me a way to segregate logs while also improving type safety in the HHVM code. Reviewed By: aorenste Differential Revision: D52598964 fbshipit-source-id: 81600b87c41adba3d07262b570016ab5710d50e1
1 parent bcea048 commit 351126a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+713
-538
lines changed

hphp/compiler/compiler.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -421,11 +421,17 @@ struct SymbolSets {
421421
};
422422
}
423423

424-
using IMap = folly_concurrent_hash_map_simd<
424+
using TMap = folly_concurrent_hash_map_simd<
425425
const StringData*,
426426
const StringData*,
427427
string_data_hash,
428-
string_data_isame
428+
string_data_tsame
429+
>;
430+
using FMap = folly_concurrent_hash_map_simd<
431+
const StringData*,
432+
const StringData*,
433+
string_data_hash,
434+
string_data_fsame
429435
>;
430436
using Map = folly_concurrent_hash_map_simd<
431437
const StringData*,
@@ -434,10 +440,10 @@ struct SymbolSets {
434440
string_data_same
435441
>;
436442

437-
IMap enums;
438-
IMap classes;
439-
IMap funcs;
440-
IMap typeAliases;
443+
TMap enums;
444+
TMap classes;
445+
FMap funcs;
446+
TMap typeAliases;
441447
Map constants;
442448
Map modules;
443449
Map units;

hphp/compiler/decl-provider.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,18 @@ struct BatchDeclProvider final: hackc::DeclProvider {
5050
// Maps from Name to serialized inside the UnitDecls given in the
5151
// constructor.
5252
using Map = hphp_fast_map<const StringData*, const std::string&>;
53-
using IMap = hphp_fast_map<
54-
const StringData*, const std::string&, string_data_hash, string_data_isame
53+
using TMap = hphp_fast_map<
54+
const StringData*, const std::string&, string_data_hash, string_data_tsame
55+
>;
56+
using FMap = hphp_fast_map<
57+
const StringData*, const std::string&, string_data_hash, string_data_fsame
5558
>;
5659

5760
// Symbols requested but not found
5861
Package::DeclNames m_missing;
5962

60-
IMap m_types;
61-
IMap m_funcs;
63+
TMap m_types;
64+
FMap m_funcs;
6265
Map m_constants;
6366
Map m_modules;
6467
};

hphp/compiler/package.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,15 @@ struct UnitIndex final {
381381
extern_worker::Ref<Package::UnitDecls> declsRef;
382382
};
383383

384-
using IMap = folly_concurrent_hash_map_simd<
384+
using TMap = folly_concurrent_hash_map_simd<
385385
const StringData*, std::shared_ptr<Locations>,
386386
string_data_hash,
387-
string_data_isame
387+
string_data_tsame
388+
>;
389+
using FMap = folly_concurrent_hash_map_simd<
390+
const StringData*, std::shared_ptr<Locations>,
391+
string_data_hash,
392+
string_data_fsame
388393
>;
389394
using Map = folly_concurrent_hash_map_simd<
390395
const StringData*, std::shared_ptr<Locations>
@@ -394,8 +399,8 @@ struct UnitIndex final {
394399
// symbol that is present in this index.
395400
bool containsAnyMissing(const Package::ParseMetaVec& parseMetas) const;
396401

397-
IMap types;
398-
IMap funcs;
402+
TMap types;
403+
FMap funcs;
399404
Map constants;
400405
Map modules;
401406
};

hphp/hack/src/parser/rust_parser_errors.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -172,27 +172,29 @@ use NamespaceType::*;
172172
#[derive(Clone, Debug)]
173173
enum Strmap<X> {
174174
YesCase(HashMap<String, X>),
175-
NoCase(HashMap<String, X>),
175+
FuncCase(HashMap<String, X>),
176+
TypeCase(HashMap<String, X>),
177+
NsCase(HashMap<String, X>),
176178
}
177179

178180
impl<X> Strmap<X> {
179181
fn mem(&self, k: &str) -> bool {
180182
match &self {
181-
NoCase(m) => m.contains_key(&k.to_ascii_lowercase()),
183+
FuncCase(m) | TypeCase(m) | NsCase(m) => m.contains_key(&k.to_ascii_lowercase()),
182184
YesCase(m) => m.contains_key(k),
183185
}
184186
}
185187

186188
fn add(&mut self, k: &str, v: X) {
187189
match self {
188-
NoCase(m) => m.insert(k.to_ascii_lowercase(), v),
190+
FuncCase(m) | TypeCase(m) | NsCase(m) => m.insert(k.to_ascii_lowercase(), v),
189191
YesCase(m) => m.insert(k.to_string(), v),
190192
};
191193
}
192194

193195
fn get(&self, k: &str) -> Option<&X> {
194196
match &self {
195-
NoCase(m) => m.get(&k.to_ascii_lowercase()),
197+
FuncCase(m) | TypeCase(m) | NsCase(m) => m.get(&k.to_ascii_lowercase()),
196198
YesCase(m) => m.get(k),
197199
}
198200
}
@@ -202,7 +204,9 @@ impl<X> Strmap<X> {
202204
F: Fn(&X) -> bool,
203205
{
204206
match self {
205-
NoCase(m) => NoCase(m.into_iter().filter(|(_, x)| f(x)).collect()),
207+
FuncCase(m) => FuncCase(m.into_iter().filter(|(_, x)| f(x)).collect()),
208+
TypeCase(m) => TypeCase(m.into_iter().filter(|(_, x)| f(x)).collect()),
209+
NsCase(m) => NsCase(m.into_iter().filter(|(_, x)| f(x)).collect()),
206210
YesCase(m) => YesCase(m.into_iter().filter(|(_, x)| f(x)).collect()),
207211
}
208212
}
@@ -211,24 +215,24 @@ impl<X> Strmap<X> {
211215
use crate::Strmap::*;
212216

213217
fn empty_trait_require_clauses() -> Strmap<TokenKind> {
214-
NoCase(HashMap::default())
218+
TypeCase(HashMap::default())
215219
}
216220

217221
#[derive(Clone, Debug)]
218222
struct UsedNames {
219-
classes: Strmap<FirstUseOrDef>, // NoCase
220-
namespaces: Strmap<FirstUseOrDef>, // NoCase
221-
functions: Strmap<FirstUseOrDef>, // NoCase
223+
classes: Strmap<FirstUseOrDef>, // TypeCase
224+
namespaces: Strmap<FirstUseOrDef>, // NsCase
225+
functions: Strmap<FirstUseOrDef>, // FuncCase
222226
constants: Strmap<FirstUseOrDef>, // YesCase
223227
attributes: Strmap<FirstUseOrDef>, // YesCase
224228
}
225229

226230
impl UsedNames {
227231
fn empty() -> Self {
228232
Self {
229-
classes: NoCase(HashMap::default()),
230-
namespaces: NoCase(HashMap::default()),
231-
functions: NoCase(HashMap::default()),
233+
classes: TypeCase(HashMap::default()),
234+
namespaces: NsCase(HashMap::default()),
235+
functions: FuncCase(HashMap::default()),
232236
constants: YesCase(HashMap::default()),
233237
attributes: YesCase(HashMap::default()),
234238
}
@@ -5624,7 +5628,7 @@ impl<'a, State: 'a + Clone> ParserErrors<'a, State> {
56245628
// Reset the function declarations
56255629

56265630
let constants = std::mem::replace(&mut self.names.constants, YesCase(HashMap::default()));
5627-
let functions = std::mem::replace(&mut self.names.functions, NoCase(HashMap::default()));
5631+
let functions = std::mem::replace(&mut self.names.functions, FuncCase(HashMap::default()));
56285632
let trait_require_clauses = std::mem::replace(
56295633
&mut self.trait_require_clauses,
56305634
empty_trait_require_clauses(),

hphp/hhbbc/check.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ bool check(const php::Func& f) {
153153
if (f.isClosureBody) {
154154
assertx(f.cls);
155155
assertx(f.cls->parentName);
156-
assertx(f.cls->parentName->isame(s_Closure.get()));
156+
assertx(f.cls->parentName->tsame(s_Closure.get()));
157157
}
158158

159159
assertx(checkExnTree(f));

hphp/hhbbc/class-util.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const StaticString
5050
bool has_magic_bool_conversion(SString clsName) {
5151
return
5252
collections::isTypeName(clsName) ||
53-
clsName->isame(s_SimpleXMLElement.get());
53+
clsName->tsame(s_SimpleXMLElement.get());
5454
}
5555

5656
bool is_collection(res::Class cls) {
@@ -90,15 +90,15 @@ bool is_noflatten_trait(const php::Class* cls) {
9090
}
9191

9292
bool is_closure_base(SString name) {
93-
return name->isame(s_Closure.get());
93+
return name->tsame(s_Closure.get());
9494
}
9595

9696
bool is_closure_base(const php::Class& c) {
97-
return c.name->isame(s_Closure.get());
97+
return c.name->tsame(s_Closure.get());
9898
}
9999

100100
bool is_closure(const php::Class& c) {
101-
return c.parentName && c.parentName->isame(s_Closure.get());
101+
return c.parentName && c.parentName->tsame(s_Closure.get());
102102
}
103103

104104
bool is_closure_name(SString name) {

hphp/hhbbc/debug.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ void dump_index(const std::string& dir,
247247
std::sort(
248248
begin(classes), end(classes),
249249
[] (const php::Class* a, const php::Class* b) {
250-
return string_data_lti{}(a->name, b->name);
250+
return string_data_lt_type{}(a->name, b->name);
251251
}
252252
);
253253

hphp/hhbbc/emit.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ EmitBcInfo emit_bytecode(EmitUnitState& euState, UnitEmitter& ue, FuncEmitter& f
507507
OpInfo<bc::opcode> data{inst.opcode}; \
508508
if (RuntimeOption::EnableIntrinsicsExtension) { \
509509
if (Op::opcode == Op::FCallFuncD && \
510-
inst.FCallFuncD.str2->isame( \
510+
inst.FCallFuncD.str2->fsame( \
511511
s_hhbbc_fail_verification.get())) { \
512512
fe.emitOp(Op::CheckProp); \
513513
fe.emitInt32( \
@@ -1097,7 +1097,7 @@ void emit_class(EmitUnitState& state, UnitEmitter& ue, PreClassEmitter* pce,
10971097
continue;
10981098
}
10991099
if (cconst.kind == ConstModifiers::Kind::Context) {
1100-
assertx(cconst.cls->isame(cls.name));
1100+
assertx(cconst.cls->tsame(cls.name));
11011101
assertx(!cconst.resolvedTypeStructure);
11021102
assertx(cconst.invariance == php::Const::Invariance::None);
11031103
pce->addContextConstant(
@@ -1107,7 +1107,7 @@ void emit_class(EmitUnitState& state, UnitEmitter& ue, PreClassEmitter* pce,
11071107
cconst.isFromTrait
11081108
);
11091109
} else if (!cconst.val.has_value()) {
1110-
assertx(cconst.cls->isame(cls.name));
1110+
assertx(cconst.cls->tsame(cls.name));
11111111
assertx(!cconst.resolvedTypeStructure);
11121112
assertx(cconst.invariance == php::Const::Invariance::None);
11131113
pce->addAbstractConstant(
@@ -1119,7 +1119,7 @@ void emit_class(EmitUnitState& state, UnitEmitter& ue, PreClassEmitter* pce,
11191119
needs86cinit |= cconst.val->m_type == KindOfUninit;
11201120
pce->addConstant(
11211121
cconst.name,
1122-
cconst.cls->isame(cls.name) ? nullptr : cconst.cls,
1122+
cconst.cls->tsame(cls.name) ? nullptr : cconst.cls,
11231123
&cconst.val.value(),
11241124
ArrNR{cconst.resolvedTypeStructure},
11251125
cconst.kind,

0 commit comments

Comments
 (0)